summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--cmds/am/src/com/android/commands/am/Am.java1
-rw-r--r--cmds/pm/src/com/android/commands/pm/Pm.java9
-rw-r--r--core/java/android/accounts/AccountManager.java49
-rw-r--r--core/java/android/accounts/AccountManagerService.java44
-rw-r--r--core/java/android/accounts/ChooseTypeAndAccountActivity.java240
-rw-r--r--core/java/android/accounts/GrantCredentialsPermissionActivity.java70
-rw-r--r--core/java/android/accounts/IAccountManager.aidl3
-rw-r--r--core/java/android/app/ActivityManagerNative.java67
-rw-r--r--core/java/android/app/ActivityThread.java473
-rw-r--r--core/java/android/app/ApplicationThreadNative.java17
-rw-r--r--core/java/android/app/ContextImpl.java15
-rw-r--r--core/java/android/app/FragmentManager.java19
-rw-r--r--core/java/android/app/IActivityManager.java14
-rw-r--r--core/java/android/app/IApplicationThread.java2
-rw-r--r--core/java/android/app/Instrumentation.java7
-rw-r--r--core/java/android/app/Notification.java31
-rw-r--r--core/java/android/app/backup/BackupManager.java10
-rw-r--r--core/java/android/content/ContentProviderClient.java133
-rw-r--r--core/java/android/content/ContentResolver.java242
-rw-r--r--core/java/android/content/pm/PackageParser.java20
-rw-r--r--core/java/android/hardware/Camera.java7
-rw-r--r--core/java/android/inputmethodservice/InputMethodService.java13
-rw-r--r--core/java/android/provider/ContactsContract.java15
-rw-r--r--core/java/android/provider/Settings.java10
-rw-r--r--core/java/android/server/BluetoothA2dpService.java59
-rw-r--r--core/java/android/text/method/BaseKeyListener.java4
-rw-r--r--core/java/android/text/method/DateKeyListener.java4
-rw-r--r--core/java/android/text/method/DateTimeKeyListener.java4
-rw-r--r--core/java/android/text/method/DialerKeyListener.java4
-rw-r--r--core/java/android/text/method/DigitsKeyListener.java4
-rw-r--r--core/java/android/text/method/KeyListener.java6
-rw-r--r--core/java/android/text/method/MultiTapKeyListener.java4
-rw-r--r--core/java/android/text/method/NumberKeyListener.java4
-rw-r--r--core/java/android/text/method/QwertyKeyListener.java4
-rw-r--r--core/java/android/text/method/TextKeyListener.java4
-rw-r--r--core/java/android/text/method/TimeKeyListener.java4
-rw-r--r--core/java/android/view/AccessibilityIterators.java168
-rwxr-xr-xcore/java/android/view/InputDevice.java12
-rwxr-xr-xcore/java/android/view/KeyEvent.java13
-rw-r--r--core/java/android/view/View.java227
-rw-r--r--core/java/android/view/inputmethod/InputConnection.java8
-rw-r--r--core/java/android/view/textservice/TextServicesManager.java2
-rw-r--r--core/java/android/webkit/AutoCompletePopup.java5
-rw-r--r--core/java/android/webkit/WebViewClassic.java8
-rw-r--r--core/java/android/webkit/WebViewInputDispatcher.java1
-rw-r--r--core/java/android/widget/AbsListView.java4
-rw-r--r--core/java/android/widget/AccessibilityIterators.java77
-rw-r--r--core/java/android/widget/Editor.java13
-rw-r--r--core/java/android/widget/TextView.java18
-rw-r--r--core/java/com/android/internal/app/ActionBarImpl.java45
-rw-r--r--core/java/com/android/internal/widget/multiwaveview/MultiWaveView.java184
-rw-r--r--core/java/com/android/internal/widget/multiwaveview/Tweener.java3
-rw-r--r--core/jni/android_database_SQLiteConnection.cpp18
-rw-r--r--core/res/AndroidManifest.xml2
-rw-r--r--core/res/res/anim-sw720dp/task_close_enter.xml12
-rw-r--r--core/res/res/anim-sw720dp/task_close_exit.xml16
-rw-r--r--core/res/res/anim-sw720dp/task_open_enter.xml12
-rw-r--r--core/res/res/anim-sw720dp/task_open_exit.xml14
-rw-r--r--core/res/res/anim/dock_bottom_enter.xml4
-rw-r--r--core/res/res/anim/dock_bottom_exit.xml4
-rw-r--r--core/res/res/anim/dock_left_enter.xml4
-rw-r--r--core/res/res/anim/dock_left_exit.xml4
-rw-r--r--core/res/res/anim/dock_right_enter.xml4
-rw-r--r--core/res/res/anim/dock_right_exit.xml4
-rw-r--r--core/res/res/anim/dock_top_enter.xml4
-rw-r--r--core/res/res/anim/dock_top_exit.xml4
-rw-r--r--core/res/res/layout/choose_selected_account_row.xml46
-rw-r--r--core/res/res/layout/choose_type_and_account.xml53
-rw-r--r--core/res/res/layout/notification_action_list.xml1
-rw-r--r--core/res/res/layout/notification_template_base.xml26
-rw-r--r--core/res/res/layout/notification_template_big_base.xml35
-rw-r--r--core/res/res/layout/notification_template_big_picture.xml1
-rw-r--r--core/res/res/layout/notification_template_big_text.xml44
-rw-r--r--core/res/res/layout/notification_template_inbox.xml56
-rw-r--r--core/res/res/values-af/strings.xml15
-rw-r--r--core/res/res/values-am/strings.xml9
-rw-r--r--core/res/res/values-ar/strings.xml9
-rw-r--r--core/res/res/values-be/strings.xml15
-rw-r--r--core/res/res/values-bg/strings.xml15
-rw-r--r--core/res/res/values-ca/strings.xml17
-rw-r--r--core/res/res/values-cs/strings.xml51
-rw-r--r--core/res/res/values-da/strings.xml15
-rw-r--r--core/res/res/values-de/strings.xml25
-rw-r--r--core/res/res/values-el/strings.xml9
-rw-r--r--core/res/res/values-en-rGB/strings.xml9
-rw-r--r--core/res/res/values-es-rUS/strings.xml15
-rw-r--r--core/res/res/values-es/strings.xml35
-rw-r--r--core/res/res/values-et/strings.xml9
-rw-r--r--core/res/res/values-fa/strings.xml9
-rw-r--r--core/res/res/values-fi/strings.xml15
-rw-r--r--core/res/res/values-fr/strings.xml17
-rw-r--r--core/res/res/values-hi/strings.xml15
-rw-r--r--core/res/res/values-hr/strings.xml15
-rw-r--r--core/res/res/values-hu/strings.xml15
-rw-r--r--core/res/res/values-in/strings.xml37
-rw-r--r--core/res/res/values-it/strings.xml15
-rw-r--r--core/res/res/values-iw/strings.xml9
-rw-r--r--core/res/res/values-ja/strings.xml15
-rw-r--r--core/res/res/values-ko/strings.xml9
-rw-r--r--core/res/res/values-large/config.xml3
-rw-r--r--core/res/res/values-lt/strings.xml9
-rw-r--r--core/res/res/values-lv/strings.xml9
-rw-r--r--core/res/res/values-ms/strings.xml9
-rw-r--r--core/res/res/values-nb/strings.xml15
-rw-r--r--core/res/res/values-nl/strings.xml15
-rw-r--r--core/res/res/values-pl/strings.xml13
-rw-r--r--core/res/res/values-pt-rPT/strings.xml15
-rw-r--r--core/res/res/values-pt/strings.xml9
-rw-r--r--core/res/res/values-rm/strings.xml16
-rw-r--r--core/res/res/values-ro/strings.xml15
-rw-r--r--core/res/res/values-ru/strings.xml15
-rw-r--r--core/res/res/values-sk/strings.xml15
-rw-r--r--core/res/res/values-sl/strings.xml15
-rw-r--r--core/res/res/values-sr/strings.xml15
-rw-r--r--core/res/res/values-sv/strings.xml15
-rw-r--r--core/res/res/values-sw/strings.xml11
-rw-r--r--core/res/res/values-sw600dp/config.xml3
-rw-r--r--core/res/res/values-th/strings.xml9
-rw-r--r--core/res/res/values-tl/strings.xml9
-rw-r--r--core/res/res/values-tr/strings.xml15
-rw-r--r--core/res/res/values-uk/strings.xml9
-rw-r--r--core/res/res/values-vi/strings.xml15
-rw-r--r--core/res/res/values-zh-rCN/strings.xml63
-rw-r--r--core/res/res/values-zh-rTW/strings.xml17
-rw-r--r--core/res/res/values-zu/strings.xml9
-rwxr-xr-xcore/res/res/values/attrs.xml37
-rw-r--r--core/res/res/values/attrs_manifest.xml4
-rwxr-xr-xcore/res/res/values/config.xml8
-rw-r--r--core/res/res/values/public.xml14
-rwxr-xr-xcore/res/res/values/strings.xml3
-rw-r--r--core/res/res/values/styles.xml9
-rw-r--r--docs/html/guide/topics/ui/index.jd4
-rw-r--r--docs/html/guide/topics/ui/ui-events.jd14
-rw-r--r--media/java/android/media/AudioManager.java37
-rw-r--r--media/java/android/media/AudioService.java175
-rw-r--r--media/java/android/media/IAudioService.aidl4
-rw-r--r--media/java/android/media/MediaPlayer.java1
-rwxr-xr-xmedia/jni/mediaeditor/VideoEditorMain.cpp11
-rw-r--r--media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/stress/MediaRecorderStressTest.java104
-rw-r--r--packages/SystemUI/res/drawable-hdpi/notification_panel_bg.9.pngbin232 -> 155 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/notification_panel_bg.9.pngbin211 -> 152 bytes
-rw-r--r--packages/SystemUI/res/drawable-sw600dp-hdpi/notification_panel_bg.9.pngbin2641 -> 983 bytes
-rw-r--r--packages/SystemUI/res/drawable-sw600dp-mdpi/notification_panel_bg.9.pngbin1496 -> 651 bytes
-rw-r--r--packages/SystemUI/res/drawable-sw600dp-xhdpi/notification_panel_bg.9.pngbin4014 -> 1516 bytes
-rw-r--r--packages/SystemUI/res/drawable-sw720dp-hdpi/notification_panel_bg.9.pngbin2641 -> 2498 bytes
-rw-r--r--packages/SystemUI/res/drawable-sw720dp-mdpi/notification_panel_bg.9.pngbin1496 -> 1551 bytes
-rw-r--r--packages/SystemUI/res/drawable-sw720dp-xhdpi/notification_panel_bg.9.pngbin4014 -> 3910 bytes
-rw-r--r--packages/SystemUI/res/drawable-xhdpi/notification_panel_bg.9.pngbin249 -> 157 bytes
-rw-r--r--packages/SystemUI/res/layout-sw600dp/status_bar_search_panel.xml69
-rw-r--r--packages/SystemUI/res/layout-sw720dp/status_bar_search_panel.xml70
-rw-r--r--packages/SystemUI/res/layout/status_bar_notification_row.xml2
-rw-r--r--packages/SystemUI/res/values-cs/strings.xml4
-rw-r--r--packages/SystemUI/res/values-de/strings.xml2
-rw-r--r--packages/SystemUI/res/values-en-rGB/strings.xml4
-rw-r--r--packages/SystemUI/res/values-es-rUS/strings.xml2
-rw-r--r--packages/SystemUI/res/values-es/strings.xml2
-rw-r--r--packages/SystemUI/res/values-sw/strings.xml4
-rw-r--r--packages/SystemUI/res/values-vi/strings.xml2
-rw-r--r--packages/SystemUI/res/values-zh-rCN/strings.xml6
-rw-r--r--packages/SystemUI/res/values/config.xml8
-rw-r--r--packages/SystemUI/src/com/android/systemui/DreamsDockLauncher.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/ExpandHelper.java33
-rw-r--r--packages/SystemUI/src/com/android/systemui/SearchPanelView.java103
-rw-r--r--packages/SystemUI/src/com/android/systemui/recent/RecentsHorizontalScrollView.java15
-rw-r--r--packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java7
-rw-r--r--packages/SystemUI/src/com/android/systemui/recent/RecentsVerticalScrollView.java24
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java6
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java17
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java124
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java68
-rw-r--r--policy/src/com/android/internal/policy/impl/FaceUnlock.java3
-rw-r--r--policy/src/com/android/internal/policy/impl/GlobalActions.java107
-rw-r--r--policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java16
-rwxr-xr-xpolicy/src/com/android/internal/policy/impl/PhoneWindowManager.java9
-rw-r--r--services/input/InputDispatcher.cpp39
-rw-r--r--services/java/com/android/server/LocationManagerService.java133
-rw-r--r--services/java/com/android/server/TextServicesManagerService.java6
-rw-r--r--services/java/com/android/server/UiModeManagerService.java24
-rw-r--r--services/java/com/android/server/WiredAccessoryObserver.java110
-rw-r--r--services/java/com/android/server/accessibility/AccessibilityManagerService.java220
-rw-r--r--services/java/com/android/server/accessibility/TouchExplorer.java2
-rw-r--r--services/java/com/android/server/am/ActivityManagerService.java470
-rw-r--r--services/java/com/android/server/am/ContentProviderConnection.java94
-rw-r--r--services/java/com/android/server/am/ContentProviderRecord.java102
-rw-r--r--services/java/com/android/server/am/ProcessRecord.java40
-rw-r--r--services/java/com/android/server/am/ProviderMap.java30
-rw-r--r--services/java/com/android/server/am/TaskRecord.java12
-rw-r--r--services/java/com/android/server/input/InputManagerService.java8
-rw-r--r--services/java/com/android/server/location/GeocoderProxy.java25
-rw-r--r--services/java/com/android/server/location/LocationProviderProxy.java29
-rw-r--r--services/java/com/android/server/wm/AppWindowAnimator.java9
-rwxr-xr-xservices/java/com/android/server/wm/WindowManagerService.java50
-rw-r--r--services/sensorservice/SensorService.cpp18
-rw-r--r--telephony/java/com/android/internal/telephony/SMSDispatcher.java7
-rw-r--r--telephony/java/com/android/internal/telephony/SmsUsageMonitor.java31
-rw-r--r--test-runner/src/android/test/mock/MockContentResolver.java5
-rw-r--r--tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContentResolver.java5
-rw-r--r--wifi/java/android/net/wifi/p2p/WifiP2pService.java28
199 files changed, 4154 insertions, 2035 deletions
diff --git a/cmds/am/src/com/android/commands/am/Am.java b/cmds/am/src/com/android/commands/am/Am.java
index cb53422..54b5836 100644
--- a/cmds/am/src/com/android/commands/am/Am.java
+++ b/cmds/am/src/com/android/commands/am/Am.java
@@ -1301,7 +1301,6 @@ public class Am {
" am display-size [reset|MxN]\n" +
" am to-uri [INTENT]\n" +
" am to-intent-uri [INTENT]\n" +
- " am switch-user <USER_ID>\n" +
"\n" +
"am start: start an Activity. Options are:\n" +
" -D: enable debugging\n" +
diff --git a/cmds/pm/src/com/android/commands/pm/Pm.java b/cmds/pm/src/com/android/commands/pm/Pm.java
index f9ff861..88a025e 100644
--- a/cmds/pm/src/com/android/commands/pm/Pm.java
+++ b/cmds/pm/src/com/android/commands/pm/Pm.java
@@ -1360,22 +1360,19 @@ public final class Pm {
System.err.println(" pm list instrumentation [-f] [TARGET-PACKAGE]");
System.err.println(" pm list features");
System.err.println(" pm list libraries");
- System.err.println(" pm list users");
System.err.println(" pm path PACKAGE");
System.err.println(" pm install [-l] [-r] [-t] [-i INSTALLER_PACKAGE_NAME] [-s] [-f]");
System.err.println(" [--algo <algorithm name> --key <key-in-hex> --iv <IV-in-hex>] PATH");
System.err.println(" pm uninstall [-k] PACKAGE");
System.err.println(" pm clear PACKAGE");
- System.err.println(" pm enable [--user USER_ID] PACKAGE_OR_COMPONENT");
- System.err.println(" pm disable [--user USER_ID] PACKAGE_OR_COMPONENT");
- System.err.println(" pm disable-user [--user USER_ID] PACKAGE_OR_COMPONENT");
+ System.err.println(" pm enable PACKAGE_OR_COMPONENT");
+ System.err.println(" pm disable PACKAGE_OR_COMPONENT");
+ System.err.println(" pm disable-user PACKAGE_OR_COMPONENT");
System.err.println(" pm grant PACKAGE PERMISSION");
System.err.println(" pm revoke PACKAGE PERMISSION");
System.err.println(" pm set-install-location [0/auto] [1/internal] [2/external]");
System.err.println(" pm get-install-location");
System.err.println(" pm set-permission-enforced PERMISSION [true|false]");
- System.err.println(" pm create-user USER_NAME");
- System.err.println(" pm remove-user USER_ID");
System.err.println("");
System.err.println("pm list packages: prints all packages, optionally only");
System.err.println(" those whose package name contains the text in FILTER. Options:");
diff --git a/core/java/android/accounts/AccountManager.java b/core/java/android/accounts/AccountManager.java
index 150880c..39e83e0 100644
--- a/core/java/android/accounts/AccountManager.java
+++ b/core/java/android/accounts/AccountManager.java
@@ -405,6 +405,55 @@ public class AccountManager {
}
/**
+ * Change whether or not an app (identified by its uid) is allowed to retrieve an authToken
+ * for an account.
+ * <p>
+ * This is only meant to be used by system activities and is not in the SDK.
+ * @param account The account whose permissions are being modified
+ * @param authTokenType The type of token whose permissions are being modified
+ * @param uid The uid that identifies the app which is being granted or revoked permission.
+ * @param value true is permission is being granted, false for revoked
+ * @hide
+ */
+ public void updateAppPermission(Account account, String authTokenType, int uid, boolean value) {
+ try {
+ mService.updateAppPermission(account, authTokenType, uid, value);
+ } catch (RemoteException e) {
+ // won't ever happen
+ throw new RuntimeException(e);
+ }
+ }
+
+ /**
+ * Get the user-friendly label associated with an authenticator's auth token.
+ * @param accountType the type of the authenticator. must not be null.
+ * @param authTokenType the token type. must not be null.
+ * @param callback callback to invoke when the result is available. may be null.
+ * @param handler the handler on which to invoke the callback, or null for the main thread
+ * @return a future containing the label string
+ * @hide
+ */
+ public AccountManagerFuture<String> getAuthTokenLabel(
+ final String accountType, final String authTokenType,
+ AccountManagerCallback<String> callback, Handler handler) {
+ if (accountType == null) throw new IllegalArgumentException("accountType is null");
+ if (authTokenType == null) throw new IllegalArgumentException("authTokenType is null");
+ return new Future2Task<String>(handler, callback) {
+ public void doWork() throws RemoteException {
+ mService.getAuthTokenLabel(mResponse, accountType, authTokenType);
+ }
+
+ @Override
+ public String bundleToResult(Bundle bundle) throws AuthenticatorException {
+ if (!bundle.containsKey(KEY_AUTH_TOKEN_LABEL)) {
+ throw new AuthenticatorException("no result in response");
+ }
+ return bundle.getString(KEY_AUTH_TOKEN_LABEL);
+ }
+ }.start();
+ }
+
+ /**
* Finds out whether a particular account has all the specified features.
* Account features are authenticator-specific string tokens identifying
* boolean account properties. For example, features are used to tell
diff --git a/core/java/android/accounts/AccountManagerService.java b/core/java/android/accounts/AccountManagerService.java
index 2b643c2..079b9bd 100644
--- a/core/java/android/accounts/AccountManagerService.java
+++ b/core/java/android/accounts/AccountManagerService.java
@@ -163,7 +163,8 @@ public class AccountManagerService
new HashMap<Account, Integer>();
private final Object cacheLock = new Object();
/** protected by the {@link #cacheLock} */
- private final HashMap<String, Account[]> accountCache = new HashMap<String, Account[]>();
+ private final HashMap<String, Account[]> accountCache =
+ new LinkedHashMap<String, Account[]>();
/** protected by the {@link #cacheLock} */
private HashMap<Account, HashMap<String, String>> userDataCache =
new HashMap<Account, HashMap<String, String>>();
@@ -296,7 +297,7 @@ public class AccountManagerService
try {
accounts.accountCache.clear();
final HashMap<String, ArrayList<String>> accountNamesByType =
- new HashMap<String, ArrayList<String>>();
+ new LinkedHashMap<String, ArrayList<String>>();
while (cursor.moveToNext()) {
final long accountId = cursor.getLong(0);
final String accountType = cursor.getString(1);
@@ -985,21 +986,25 @@ public class AccountManagerService
}
}
- void getAuthTokenLabel(final IAccountManagerResponse response,
- final Account account,
- final String authTokenType, int uid) {
- if (account == null) throw new IllegalArgumentException("account is null");
+ public void getAuthTokenLabel(IAccountManagerResponse response, final String accountType,
+ final String authTokenType)
+ throws RemoteException {
+ if (accountType == null) throw new IllegalArgumentException("accountType is null");
if (authTokenType == null) throw new IllegalArgumentException("authTokenType is null");
- checkBinderPermission(Manifest.permission.USE_CREDENTIALS);
- UserAccounts accounts = getUserAccounts(UserId.getUserId(uid));
+ final int callingUid = getCallingUid();
+ clearCallingIdentity();
+ if (callingUid != android.os.Process.SYSTEM_UID) {
+ throw new SecurityException("can only call from system");
+ }
+ UserAccounts accounts = getUserAccounts(UserId.getUserId(callingUid));
long identityToken = clearCallingIdentity();
try {
- new Session(accounts, response, account.type, false,
+ new Session(accounts, response, accountType, false,
false /* stripAuthTokenFromResult */) {
protected String toDebugString(long now) {
return super.toDebugString(now) + ", getAuthTokenLabel"
- + ", " + account
+ + ", " + accountType
+ ", authTokenType " + authTokenType;
}
@@ -2230,6 +2235,21 @@ public class AccountManagerService
Manifest.permission.USE_CREDENTIALS);
}
+ public void updateAppPermission(Account account, String authTokenType, int uid, boolean value)
+ throws RemoteException {
+ final int callingUid = getCallingUid();
+
+ if (callingUid != android.os.Process.SYSTEM_UID) {
+ throw new SecurityException();
+ }
+
+ if (value) {
+ grantAppPermission(account, authTokenType, uid);
+ } else {
+ revokeAppPermission(account, authTokenType, uid);
+ }
+ }
+
/**
* Allow callers with the given uid permission to get credentials for account/authTokenType.
* <p>
@@ -2237,7 +2257,7 @@ public class AccountManagerService
* which is in the system. This means we don't need to protect it with permissions.
* @hide
*/
- public void grantAppPermission(Account account, String authTokenType, int uid) {
+ private void grantAppPermission(Account account, String authTokenType, int uid) {
if (account == null || authTokenType == null) {
Log.e(TAG, "grantAppPermission: called with invalid arguments", new Exception());
return;
@@ -2271,7 +2291,7 @@ public class AccountManagerService
* which is in the system. This means we don't need to protect it with permissions.
* @hide
*/
- public void revokeAppPermission(Account account, String authTokenType, int uid) {
+ private void revokeAppPermission(Account account, String authTokenType, int uid) {
if (account == null || authTokenType == null) {
Log.e(TAG, "revokeAppPermission: called with invalid arguments", new Exception());
return;
diff --git a/core/java/android/accounts/ChooseTypeAndAccountActivity.java b/core/java/android/accounts/ChooseTypeAndAccountActivity.java
index 291e75e..8543848 100644
--- a/core/java/android/accounts/ChooseTypeAndAccountActivity.java
+++ b/core/java/android/accounts/ChooseTypeAndAccountActivity.java
@@ -16,24 +16,19 @@
package android.accounts;
import android.app.Activity;
-import android.content.Context;
import android.content.Intent;
-import android.content.pm.PackageManager;
-import android.content.res.Resources;
-import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.os.Parcelable;
import android.text.TextUtils;
import android.util.Log;
-import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
-import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
+
import com.android.internal.R;
import java.io.IOException;
@@ -106,10 +101,16 @@ public class ChooseTypeAndAccountActivity extends Activity
private static final String KEY_INSTANCE_STATE_PENDING_REQUEST = "pendingRequest";
private static final String KEY_INSTANCE_STATE_EXISTING_ACCOUNTS = "existingAccounts";
+ private static final String KEY_INSTANCE_STATE_SELECTED_ACCOUNT_NAME = "selectedAccountName";
+ private static final String KEY_INSTANCE_STATE_SELECTED_ADD_ACCOUNT = "selectedAddAccount";
+
+ private static final int SELECTED_ITEM_NONE = -1;
- private ArrayList<AccountInfo> mAccountInfos;
+ private ArrayList<Account> mAccounts;
private int mPendingRequest = REQUEST_NULL;
private Parcelable[] mExistingAccounts = null;
+ private int mSelectedItemIndex;
+ private Button mOkButton;
@Override
public void onCreate(Bundle savedInstanceState) {
@@ -119,31 +120,39 @@ public class ChooseTypeAndAccountActivity extends Activity
+ savedInstanceState + ")");
}
+ // save some items we use frequently
+ final AccountManager accountManager = AccountManager.get(this);
+ final Intent intent = getIntent();
+
+ String selectedAccountName = null;
+ boolean selectedAddNewAccount = false;
+
if (savedInstanceState != null) {
mPendingRequest = savedInstanceState.getInt(KEY_INSTANCE_STATE_PENDING_REQUEST);
mExistingAccounts =
savedInstanceState.getParcelableArray(KEY_INSTANCE_STATE_EXISTING_ACCOUNTS);
+
+ // Makes sure that any user selection is preserved across orientation changes.
+ selectedAccountName = savedInstanceState.getString(
+ KEY_INSTANCE_STATE_SELECTED_ACCOUNT_NAME);
+
+ selectedAddNewAccount = savedInstanceState.getBoolean(
+ KEY_INSTANCE_STATE_SELECTED_ADD_ACCOUNT, false);
} else {
mPendingRequest = REQUEST_NULL;
mExistingAccounts = null;
+ // If the selected account as specified in the intent matches one in the list we will
+ // show is as pre-selected.
+ Account selectedAccount = (Account) intent.getParcelableExtra(EXTRA_SELECTED_ACCOUNT);
+ if (selectedAccount != null) {
+ selectedAccountName = selectedAccount.name;
+ }
}
- // save some items we use frequently
- final AccountManager accountManager = AccountManager.get(this);
- final Intent intent = getIntent();
-
- // override the description text if supplied
- final String descriptionOverride =
- intent.getStringExtra(EXTRA_DESCRIPTION_TEXT_OVERRIDE);
- if (!TextUtils.isEmpty(descriptionOverride)) {
- ((TextView)findViewById(R.id.description)).setText(descriptionOverride);
+ if (Log.isLoggable(TAG, Log.VERBOSE)) {
+ Log.v(TAG, "selected account name is " + selectedAccountName);
}
- // If the selected account matches one in the list we will place a
- // checkmark next to it.
- final Account selectedAccount =
- (Account)intent.getParcelableExtra(EXTRA_SELECTED_ACCOUNT);
-
// build an efficiently queryable map of account types to authenticator descriptions
final HashMap<String, AuthenticatorDescription> typeToAuthDescription =
new HashMap<String, AuthenticatorDescription>();
@@ -192,7 +201,8 @@ public class ChooseTypeAndAccountActivity extends Activity
// accounts that don't match the allowable types, if provided, or that don't match the
// allowable accounts, if provided.
final Account[] accounts = accountManager.getAccounts();
- mAccountInfos = new ArrayList<AccountInfo>(accounts.length);
+ mAccounts = new ArrayList<Account>(accounts.length);
+ mSelectedItemIndex = SELECTED_ITEM_NONE;
for (Account account : accounts) {
if (setOfAllowableAccounts != null
&& !setOfAllowableAccounts.contains(account)) {
@@ -202,15 +212,16 @@ public class ChooseTypeAndAccountActivity extends Activity
&& !setOfRelevantAccountTypes.contains(account.type)) {
continue;
}
- mAccountInfos.add(new AccountInfo(account,
- getDrawableForType(typeToAuthDescription, account.type),
- account.equals(selectedAccount)));
+ if (account.name.equals(selectedAccountName)) {
+ mSelectedItemIndex = mAccounts.size();
+ }
+ mAccounts.add(account);
}
if (mPendingRequest == REQUEST_NULL) {
- // If there are no relevant accounts and only one relevant account typoe go directly to
+ // If there are no relevant accounts and only one relevant account type go directly to
// add account. Otherwise let the user choose.
- if (mAccountInfos.isEmpty()) {
+ if (mAccounts.isEmpty()) {
if (setOfRelevantAccountTypes.size() == 1) {
runAddAccountForAuthenticator(setOfRelevantAccountTypes.iterator().next());
} else {
@@ -221,36 +232,71 @@ public class ChooseTypeAndAccountActivity extends Activity
// if there is only one allowable account return it
if (!intent.getBooleanExtra(EXTRA_ALWAYS_PROMPT_FOR_ACCOUNT, false)
- && mAccountInfos.size() == 1) {
- Account account = mAccountInfos.get(0).account;
+ && mAccounts.size() == 1) {
+ Account account = mAccounts.get(0);
setResultAndFinish(account.name, account.type);
return;
}
}
+ // Cannot set content view until we know that mPendingRequest is not null, otherwise
+ // would cause screen flicker.
setContentView(R.layout.choose_type_and_account);
- // there is more than one allowable account. initialize the list adapter to allow
- // the user to select an account.
+ // Override the description text if supplied
+ final String descriptionOverride =
+ intent.getStringExtra(EXTRA_DESCRIPTION_TEXT_OVERRIDE);
+ TextView descriptionView = (TextView) findViewById(R.id.description);
+ if (!TextUtils.isEmpty(descriptionOverride)) {
+ descriptionView.setText(descriptionOverride);
+ } else {
+ descriptionView.setVisibility(View.GONE);
+ }
+
+ // List of options includes all accounts found together with "Add new account" as the
+ // last item in the list.
+ String[] listItems = new String[mAccounts.size() + 1];
+ for (int i = 0; i < mAccounts.size(); i++) {
+ listItems[i] = mAccounts.get(i).name;
+ }
+ listItems[mAccounts.size()] = getResources().getString(
+ R.string.add_account_button_label);
+
ListView list = (ListView) findViewById(android.R.id.list);
- list.setAdapter(new AccountArrayAdapter(this,
- android.R.layout.simple_list_item_1, mAccountInfos));
+ list.setAdapter(new ArrayAdapter<String>(this,
+ android.R.layout.simple_list_item_single_choice, listItems));
list.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
+ list.setItemsCanFocus(false);
list.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View v, int position, long id) {
- onListItemClick((ListView)parent, v, position, id);
+ mSelectedItemIndex = position;
+ mOkButton.setEnabled(true);
}
});
- // set the listener for the addAccount button
- Button addAccountButton = (Button) findViewById(R.id.addAccount);
- addAccountButton.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(final View v) {
- startChooseAccountTypeActivity();
+ // If "Add account" option was previously selected by user, preserve it across
+ // orientation changes.
+ if (selectedAddNewAccount) {
+ mSelectedItemIndex = mAccounts.size();
+ }
+ if (Log.isLoggable(TAG, Log.VERBOSE)) {
+ Log.v(TAG, "mSelectedItemIndex is " + mSelectedItemIndex);
+ }
+
+ ViewGroup buttonBar = (ViewGroup) findViewById(R.id.button_bar);
+ if (buttonBar != null) {
+ mOkButton = (Button) buttonBar.findViewById(android.R.id.button2);
+ if (mSelectedItemIndex != SELECTED_ITEM_NONE) {
+ // If caller specified a selectedAccount, then display that as selected and enable
+ // the "OK" button by default.
+ list.setSelection(mSelectedItemIndex);
+ mOkButton.setEnabled(true);
+ } else {
+ // Otherwise "OK" button is disabled since nothing is pre-selected.
+ mOkButton.setEnabled(false);
}
- });
+ }
}
@Override
@@ -268,6 +314,28 @@ public class ChooseTypeAndAccountActivity extends Activity
if (mPendingRequest == REQUEST_ADD_ACCOUNT) {
outState.putParcelableArray(KEY_INSTANCE_STATE_EXISTING_ACCOUNTS, mExistingAccounts);
}
+ if (mSelectedItemIndex != SELECTED_ITEM_NONE) {
+ if (mSelectedItemIndex == mAccounts.size()) {
+ outState.putBoolean(KEY_INSTANCE_STATE_SELECTED_ADD_ACCOUNT, true);
+ } else {
+ outState.putBoolean(KEY_INSTANCE_STATE_SELECTED_ADD_ACCOUNT, false);
+ outState.putString(KEY_INSTANCE_STATE_SELECTED_ACCOUNT_NAME,
+ mAccounts.get(mSelectedItemIndex).name);
+ }
+ }
+ }
+
+ public void onCancelButtonClicked(View view) {
+ onBackPressed();
+ }
+
+ public void onOkButtonClicked(View view) {
+ if (mSelectedItemIndex == mAccounts.size()) {
+ // Selected "Add New Account" option
+ startChooseAccountTypeActivity();
+ } else if (mSelectedItemIndex != SELECTED_ITEM_NONE) {
+ onAccountSelected(mAccounts.get(mSelectedItemIndex));
+ }
}
// Called when the choose account type activity (for adding an account) returns.
@@ -287,9 +355,9 @@ public class ChooseTypeAndAccountActivity extends Activity
mPendingRequest = REQUEST_NULL;
if (resultCode == RESULT_CANCELED) {
- // if cancelling out of addAccount and the original state caused us to skip this,
+ // if canceling out of addAccount and the original state caused us to skip this,
// finish this activity
- if (mAccountInfos.isEmpty()) {
+ if (mAccounts.isEmpty()) {
setResult(Activity.RESULT_CANCELED);
finish();
}
@@ -360,6 +428,7 @@ public class ChooseTypeAndAccountActivity extends Activity
options, null /* activity */, this /* callback */, null /* Handler */);
}
+ @Override
public void run(final AccountManagerFuture<Bundle> accountManagerFuture) {
try {
final Bundle accountManagerResult = accountManagerFuture.getResult();
@@ -385,34 +454,9 @@ public class ChooseTypeAndAccountActivity extends Activity
finish();
}
- private Drawable getDrawableForType(
- final HashMap<String, AuthenticatorDescription> typeToAuthDescription,
- String accountType) {
- Drawable icon = null;
- if (typeToAuthDescription.containsKey(accountType)) {
- try {
- AuthenticatorDescription desc = typeToAuthDescription.get(accountType);
- Context authContext = createPackageContext(desc.packageName, 0);
- icon = authContext.getResources().getDrawable(desc.iconId);
- } catch (PackageManager.NameNotFoundException e) {
- // Nothing we can do much here, just log
- if (Log.isLoggable(TAG, Log.WARN)) {
- Log.w(TAG, "No icon name for account type " + accountType);
- }
- } catch (Resources.NotFoundException e) {
- // Nothing we can do much here, just log
- if (Log.isLoggable(TAG, Log.WARN)) {
- Log.w(TAG, "No icon resource for account type " + accountType);
- }
- }
- }
- return icon;
- }
-
- protected void onListItemClick(ListView l, View v, int position, long id) {
- AccountInfo accountInfo = mAccountInfos.get(position);
- Log.d(TAG, "selected account " + accountInfo.account);
- setResultAndFinish(accountInfo.account.name, accountInfo.account.type);
+ private void onAccountSelected(Account account) {
+ Log.d(TAG, "selected account " + account);
+ setResultAndFinish(account.name, account.type);
}
private void setResultAndFinish(final String accountName, final String accountType) {
@@ -444,58 +488,4 @@ public class ChooseTypeAndAccountActivity extends Activity
startActivityForResult(intent, REQUEST_CHOOSE_TYPE);
mPendingRequest = REQUEST_CHOOSE_TYPE;
}
-
- private static class AccountInfo {
- final Account account;
- final Drawable drawable;
- private final boolean checked;
-
- AccountInfo(Account account, Drawable drawable, boolean checked) {
- this.account = account;
- this.drawable = drawable;
- this.checked = checked;
- }
- }
-
- private static class ViewHolder {
- ImageView icon;
- TextView text;
- ImageView checkmark;
- }
-
- private static class AccountArrayAdapter extends ArrayAdapter<AccountInfo> {
- private LayoutInflater mLayoutInflater;
- private ArrayList<AccountInfo> mInfos;
-
- public AccountArrayAdapter(Context context, int textViewResourceId,
- ArrayList<AccountInfo> infos) {
- super(context, textViewResourceId, infos);
- mInfos = infos;
- mLayoutInflater = (LayoutInflater) context.getSystemService(
- Context.LAYOUT_INFLATER_SERVICE);
- }
-
- @Override
- public View getView(int position, View convertView, ViewGroup parent) {
- ViewHolder holder;
-
- if (convertView == null) {
- convertView = mLayoutInflater.inflate(R.layout.choose_selected_account_row, null);
- holder = new ViewHolder();
- holder.text = (TextView) convertView.findViewById(R.id.account_row_text);
- holder.icon = (ImageView) convertView.findViewById(R.id.account_row_icon);
- holder.checkmark = (ImageView) convertView.findViewById(R.id.account_row_checkmark);
- convertView.setTag(holder);
- } else {
- holder = (ViewHolder) convertView.getTag();
- }
-
- holder.text.setText(mInfos.get(position).account.name);
- holder.icon.setImageDrawable(mInfos.get(position).drawable);
- final int displayCheckmark =
- mInfos.get(position).checked ? View.VISIBLE : View.INVISIBLE;
- holder.checkmark.setVisibility(displayCheckmark);
- return convertView;
- }
- }
}
diff --git a/core/java/android/accounts/GrantCredentialsPermissionActivity.java b/core/java/android/accounts/GrantCredentialsPermissionActivity.java
index 4419c8c..8b01c6a 100644
--- a/core/java/android/accounts/GrantCredentialsPermissionActivity.java
+++ b/core/java/android/accounts/GrantCredentialsPermissionActivity.java
@@ -16,22 +16,22 @@
package android.accounts;
import android.app.Activity;
+import android.content.pm.RegisteredServicesCache;
+import android.content.res.Resources;
import android.os.Bundle;
-import android.os.RemoteException;
import android.widget.TextView;
import android.widget.LinearLayout;
-import android.widget.ImageView;
import android.view.View;
import android.view.LayoutInflater;
-import android.view.Window;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
-import android.content.pm.RegisteredServicesCache;
import android.text.TextUtils;
-import android.graphics.drawable.Drawable;
import com.android.internal.R;
+import java.io.IOException;
+import java.net.Authenticator;
+
/**
* @hide
*/
@@ -48,7 +48,6 @@ public class GrantCredentialsPermissionActivity extends Activity implements View
private int mUid;
private Bundle mResultBundle = null;
protected LayoutInflater mInflater;
- private final AccountManagerService accountManagerService = AccountManagerService.getSingleton();
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@@ -81,7 +80,7 @@ public class GrantCredentialsPermissionActivity extends Activity implements View
String accountTypeLabel;
try {
- accountTypeLabel = accountManagerService.getAccountLabel(mAccount.type);
+ accountTypeLabel = getAccountLabel(mAccount);
} catch (IllegalArgumentException e) {
// label or resource was missing. abort the activity.
setResult(Activity.RESULT_CANCELED);
@@ -92,28 +91,27 @@ public class GrantCredentialsPermissionActivity extends Activity implements View
final TextView authTokenTypeView = (TextView) findViewById(R.id.authtoken_type);
authTokenTypeView.setVisibility(View.GONE);
- /** Handles the responses from the AccountManager */
- IAccountManagerResponse response = new IAccountManagerResponse.Stub() {
- public void onResult(Bundle bundle) {
- final String authTokenLabel =
- bundle.getString(AccountManager.KEY_AUTH_TOKEN_LABEL);
- if (!TextUtils.isEmpty(authTokenLabel)) {
- runOnUiThread(new Runnable() {
- public void run() {
- if (!isFinishing()) {
- authTokenTypeView.setText(authTokenLabel);
- authTokenTypeView.setVisibility(View.VISIBLE);
+ final AccountManagerCallback<String> callback = new AccountManagerCallback<String>() {
+ public void run(AccountManagerFuture<String> future) {
+ try {
+ final String authTokenLabel = future.getResult();
+ if (!TextUtils.isEmpty(authTokenLabel)) {
+ runOnUiThread(new Runnable() {
+ public void run() {
+ if (!isFinishing()) {
+ authTokenTypeView.setText(authTokenLabel);
+ authTokenTypeView.setVisibility(View.VISIBLE);
+ }
}
- }
- });
+ });
+ }
+ } catch (OperationCanceledException e) {
+ } catch (IOException e) {
+ } catch (AuthenticatorException e) {
}
}
-
- public void onError(int code, String message) {
- }
};
-
- accountManagerService.getAuthTokenLabel(response, mAccount, mAuthTokenType, mUid);
+ AccountManager.get(this).getAuthTokenLabel(mAccount.type, mAuthTokenType, callback, null);
findViewById(R.id.allow_button).setOnClickListener(this);
findViewById(R.id.deny_button).setOnClickListener(this);
@@ -134,6 +132,24 @@ public class GrantCredentialsPermissionActivity extends Activity implements View
((TextView) findViewById(R.id.account_type)).setText(accountTypeLabel);
}
+ private String getAccountLabel(Account account) {
+ final AuthenticatorDescription[] authenticatorTypes =
+ AccountManager.get(this).getAuthenticatorTypes();
+ for (int i = 0, N = authenticatorTypes.length; i < N; i++) {
+ final AuthenticatorDescription desc = authenticatorTypes[i];
+ if (desc.type.equals(account.type)) {
+ try {
+ return createPackageContext(desc.packageName, 0).getString(desc.labelId);
+ } catch (PackageManager.NameNotFoundException e) {
+ return account.type;
+ } catch (Resources.NotFoundException e) {
+ return account.type;
+ }
+ }
+ }
+ return account.type;
+ }
+
private View newPackageView(String packageLabel) {
View view = mInflater.inflate(R.layout.permissions_package_list_item, null);
((TextView) view.findViewById(R.id.package_label)).setText(packageLabel);
@@ -143,7 +159,7 @@ public class GrantCredentialsPermissionActivity extends Activity implements View
public void onClick(View v) {
switch (v.getId()) {
case R.id.allow_button:
- accountManagerService.grantAppPermission(mAccount, mAuthTokenType, mUid);
+ AccountManager.get(this).updateAppPermission(mAccount, mAuthTokenType, mUid, true);
Intent result = new Intent();
result.putExtra("retry", true);
setResult(RESULT_OK, result);
@@ -151,7 +167,7 @@ public class GrantCredentialsPermissionActivity extends Activity implements View
break;
case R.id.deny_button:
- accountManagerService.revokeAppPermission(mAccount, mAuthTokenType, mUid);
+ AccountManager.get(this).updateAppPermission(mAccount, mAuthTokenType, mUid, false);
setResult(RESULT_CANCELED);
break;
}
diff --git a/core/java/android/accounts/IAccountManager.aidl b/core/java/android/accounts/IAccountManager.aidl
index 36a5653..6007321 100644
--- a/core/java/android/accounts/IAccountManager.aidl
+++ b/core/java/android/accounts/IAccountManager.aidl
@@ -41,6 +41,7 @@ interface IAccountManager {
void setPassword(in Account account, String password);
void clearPassword(in Account account);
void setUserData(in Account account, String key, String value);
+ void updateAppPermission(in Account account, String authTokenType, int uid, boolean value);
void getAuthToken(in IAccountManagerResponse response, in Account account,
String authTokenType, boolean notifyOnAuthFailure, boolean expectActivityLaunch,
@@ -54,4 +55,6 @@ interface IAccountManager {
boolean expectActivityLaunch);
void confirmCredentials(in IAccountManagerResponse response, in Account account,
in Bundle options, boolean expectActivityLaunch);
+ void getAuthTokenLabel(in IAccountManagerResponse response, String accountType,
+ String authTokenType);
}
diff --git a/core/java/android/app/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java
index 4506546..2ed93f4 100644
--- a/core/java/android/app/ActivityManagerNative.java
+++ b/core/java/android/app/ActivityManagerNative.java
@@ -580,7 +580,8 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM
IBinder b = data.readStrongBinder();
IApplicationThread app = ApplicationThreadNative.asInterface(b);
String name = data.readString();
- ContentProviderHolder cph = getContentProvider(app, name);
+ boolean stable = data.readInt() != 0;
+ ContentProviderHolder cph = getContentProvider(app, name, stable);
reply.writeNoException();
if (cph != null) {
reply.writeInt(1);
@@ -617,12 +618,30 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM
return true;
}
+ case REF_CONTENT_PROVIDER_TRANSACTION: {
+ data.enforceInterface(IActivityManager.descriptor);
+ IBinder b = data.readStrongBinder();
+ int stable = data.readInt();
+ int unstable = data.readInt();
+ boolean res = refContentProvider(b, stable, unstable);
+ reply.writeNoException();
+ reply.writeInt(res ? 1 : 0);
+ return true;
+ }
+
+ case UNSTABLE_PROVIDER_DIED_TRANSACTION: {
+ data.enforceInterface(IActivityManager.descriptor);
+ IBinder b = data.readStrongBinder();
+ unstableProviderDied(b);
+ reply.writeNoException();
+ return true;
+ }
+
case REMOVE_CONTENT_PROVIDER_TRANSACTION: {
data.enforceInterface(IActivityManager.descriptor);
IBinder b = data.readStrongBinder();
- IApplicationThread app = ApplicationThreadNative.asInterface(b);
- String name = data.readString();
- removeContentProvider(app, name);
+ boolean stable = data.readInt() != 0;
+ removeContentProvider(b, stable);
reply.writeNoException();
return true;
}
@@ -2314,13 +2333,13 @@ class ActivityManagerProxy implements IActivityManager
reply.recycle();
}
public ContentProviderHolder getContentProvider(IApplicationThread caller,
- String name) throws RemoteException
- {
+ String name, boolean stable) throws RemoteException {
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
data.writeInterfaceToken(IActivityManager.descriptor);
data.writeStrongBinder(caller != null ? caller.asBinder() : null);
data.writeString(name);
+ data.writeInt(stable ? 1 : 0);
mRemote.transact(GET_CONTENT_PROVIDER_TRANSACTION, data, reply, 0);
reply.readException();
int res = reply.readInt();
@@ -2352,7 +2371,7 @@ class ActivityManagerProxy implements IActivityManager
return cph;
}
public void publishContentProviders(IApplicationThread caller,
- List<ContentProviderHolder> providers) throws RemoteException
+ List<ContentProviderHolder> providers) throws RemoteException
{
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
@@ -2364,14 +2383,38 @@ class ActivityManagerProxy implements IActivityManager
data.recycle();
reply.recycle();
}
-
- public void removeContentProvider(IApplicationThread caller,
- String name) throws RemoteException {
+ public boolean refContentProvider(IBinder connection, int stable, int unstable)
+ throws RemoteException {
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
data.writeInterfaceToken(IActivityManager.descriptor);
- data.writeStrongBinder(caller != null ? caller.asBinder() : null);
- data.writeString(name);
+ data.writeStrongBinder(connection);
+ data.writeInt(stable);
+ data.writeInt(unstable);
+ mRemote.transact(REF_CONTENT_PROVIDER_TRANSACTION, data, reply, 0);
+ reply.readException();
+ boolean res = reply.readInt() != 0;
+ data.recycle();
+ reply.recycle();
+ return res;
+ }
+ public void unstableProviderDied(IBinder connection) throws RemoteException {
+ Parcel data = Parcel.obtain();
+ Parcel reply = Parcel.obtain();
+ data.writeInterfaceToken(IActivityManager.descriptor);
+ data.writeStrongBinder(connection);
+ mRemote.transact(UNSTABLE_PROVIDER_DIED_TRANSACTION, data, reply, 0);
+ reply.readException();
+ data.recycle();
+ reply.recycle();
+ }
+
+ public void removeContentProvider(IBinder connection, boolean stable) throws RemoteException {
+ Parcel data = Parcel.obtain();
+ Parcel reply = Parcel.obtain();
+ data.writeInterfaceToken(IActivityManager.descriptor);
+ data.writeStrongBinder(connection);
+ data.writeInt(stable ? 1 : 0);
mRemote.transact(REMOVE_CONTENT_PROVIDER_TRANSACTION, data, reply, 0);
reply.readException();
data.recycle();
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 33e639e..7242029 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -140,6 +140,7 @@ public final class ActivityThread {
private static final boolean DEBUG_CONFIGURATION = false;
private static final boolean DEBUG_SERVICE = false;
private static final boolean DEBUG_MEMORY_TRIM = false;
+ private static final boolean DEBUG_PROVIDER = false;
private static final long MIN_TIME_BETWEEN_GCS = 5*1000;
private static final Pattern PATTERN_SEMICOLON = Pattern.compile(";");
private static final int SQLITE_MEM_RELEASED_EVENT_LOG_TAG = 75003;
@@ -210,6 +211,8 @@ public final class ActivityThread {
= new HashMap<IBinder, ProviderRefCount>();
final HashMap<IBinder, ProviderClientRecord> mLocalProviders
= new HashMap<IBinder, ProviderClientRecord>();
+ final HashMap<ComponentName, ProviderClientRecord> mLocalProvidersByName
+ = new HashMap<ComponentName, ProviderClientRecord>();
final HashMap<Activity, ArrayList<OnActivityPausedListener>> mOnPauseListeners
= new HashMap<Activity, ArrayList<OnActivityPausedListener>>();
@@ -284,20 +287,19 @@ public final class ActivityThread {
}
}
- final class ProviderClientRecord implements IBinder.DeathRecipient {
- final String mName;
+ final class ProviderClientRecord {
+ final String[] mNames;
final IContentProvider mProvider;
final ContentProvider mLocalProvider;
+ final IActivityManager.ContentProviderHolder mHolder;
- ProviderClientRecord(String name, IContentProvider provider,
- ContentProvider localProvider) {
- mName = name;
+ ProviderClientRecord(String[] names, IContentProvider provider,
+ ContentProvider localProvider,
+ IActivityManager.ContentProviderHolder holder) {
+ mNames = names;
mProvider = provider;
mLocalProvider = localProvider;
- }
-
- public void binderDied() {
- removeDeadProvider(mName, mProvider);
+ mHolder = holder;
}
}
@@ -1061,6 +1063,11 @@ public final class ActivityThread {
pw.flush();
}
+ @Override
+ public void unstableProviderDied(IBinder provider) {
+ queueOrSendMessage(H.UNSTABLE_PROVIDER_DIED, provider);
+ }
+
private void printRow(PrintWriter pw, String format, Object...objs) {
pw.println(String.format(format, objs));
}
@@ -1125,6 +1132,7 @@ public final class ActivityThread {
public static final int UPDATE_PACKAGE_COMPATIBILITY_INFO = 139;
public static final int TRIM_MEMORY = 140;
public static final int DUMP_PROVIDER = 141;
+ public static final int UNSTABLE_PROVIDER_DIED = 142;
String codeToString(int code) {
if (DEBUG_MESSAGES) {
switch (code) {
@@ -1170,6 +1178,7 @@ public final class ActivityThread {
case UPDATE_PACKAGE_COMPATIBILITY_INFO: return "UPDATE_PACKAGE_COMPATIBILITY_INFO";
case TRIM_MEMORY: return "TRIM_MEMORY";
case DUMP_PROVIDER: return "DUMP_PROVIDER";
+ case UNSTABLE_PROVIDER_DIED: return "UNSTABLE_PROVIDER_DIED";
}
}
return Integer.toString(code);
@@ -1337,7 +1346,7 @@ public final class ActivityThread {
break;
case REMOVE_PROVIDER:
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "providerRemove");
- completeRemoveProvider((IContentProvider)msg.obj);
+ completeRemoveProvider((ProviderRefCount)msg.obj);
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
break;
case ENABLE_JIT:
@@ -1377,6 +1386,9 @@ public final class ActivityThread {
handleTrimMemory(msg.arg1);
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
break;
+ case UNSTABLE_PROVIDER_DIED:
+ handleUnstableProviderDied((IBinder)msg.obj, false);
+ break;
}
if (DEBUG_MESSAGES) Slog.v(TAG, "<<< done: " + codeToString(msg.what));
}
@@ -2867,10 +2879,24 @@ public final class ActivityThread {
}
private static final class ProviderRefCount {
- public int count;
+ public final IActivityManager.ContentProviderHolder holder;
+ public final ProviderClientRecord client;
+ public int stableCount;
+ public int unstableCount;
- ProviderRefCount(int pCount) {
- count = pCount;
+ // When this is set, the stable and unstable ref counts are 0 and
+ // we have a pending operation scheduled to remove the ref count
+ // from the activity manager. On the activity manager we are still
+ // holding an unstable ref, though it is not reflected in the counts
+ // here.
+ public boolean removePending;
+
+ ProviderRefCount(IActivityManager.ContentProviderHolder inHolder,
+ ProviderClientRecord inClient, int sCount, int uCount) {
+ holder = inHolder;
+ client = inClient;
+ stableCount = sCount;
+ unstableCount = uCount;
}
}
@@ -4080,15 +4106,6 @@ public final class ActivityThread {
Debug.startMethodTracing(file.toString(), 8 * 1024 * 1024);
}
- try {
- mInstrumentation.onCreate(data.instrumentationArgs);
- }
- catch (Exception e) {
- throw new RuntimeException(
- "Exception thrown in onCreate() of "
- + data.instrumentationName + ": " + e.toString(), e);
- }
-
} else {
mInstrumentation = new Instrumentation();
}
@@ -4119,6 +4136,17 @@ public final class ActivityThread {
}
}
+ // Do this after providers, since instrumentation tests generally start their
+ // test thread at this point, and we don't want that racing.
+ try {
+ mInstrumentation.onCreate(data.instrumentationArgs);
+ }
+ catch (Exception e) {
+ throw new RuntimeException(
+ "Exception thrown in onCreate() of "
+ + data.instrumentationName + ": " + e.toString(), e);
+ }
+
try {
mInstrumentation.callApplicationOnCreate(app);
} catch (Exception e) {
@@ -4159,12 +4187,9 @@ public final class ActivityThread {
buf.append(": ");
buf.append(cpi.name);
Log.i(TAG, buf.toString());
- IContentProvider cp = installProvider(context, null, cpi,
- false /*noisy*/, true /*noReleaseNeeded*/);
- if (cp != null) {
- IActivityManager.ContentProviderHolder cph =
- new IActivityManager.ContentProviderHolder(cpi);
- cph.provider = cp;
+ IActivityManager.ContentProviderHolder cph = installProvider(context, null, cpi,
+ false /*noisy*/, true /*noReleaseNeeded*/, true /*stable*/);
+ if (cph != null) {
cph.noReleaseNeeded = true;
results.add(cph);
}
@@ -4177,8 +4202,8 @@ public final class ActivityThread {
}
}
- public final IContentProvider acquireProvider(Context c, String name) {
- IContentProvider provider = acquireExistingProvider(c, name);
+ public final IContentProvider acquireProvider(Context c, String name, boolean stable) {
+ IContentProvider provider = acquireExistingProvider(c, name, stable);
if (provider != null) {
return provider;
}
@@ -4192,7 +4217,7 @@ public final class ActivityThread {
IActivityManager.ContentProviderHolder holder = null;
try {
holder = ActivityManagerNative.getDefault().getContentProvider(
- getApplicationThread(), name);
+ getApplicationThread(), name, stable);
} catch (RemoteException ex) {
}
if (holder == null) {
@@ -4202,23 +4227,79 @@ public final class ActivityThread {
// Install provider will increment the reference count for us, and break
// any ties in the race.
- provider = installProvider(c, holder.provider, holder.info,
- true /*noisy*/, holder.noReleaseNeeded);
- if (holder.provider != null && provider != holder.provider) {
- if (localLOGV) {
- Slog.v(TAG, "acquireProvider: lost the race, releasing extraneous "
- + "reference to the content provider");
+ holder = installProvider(c, holder, holder.info,
+ true /*noisy*/, holder.noReleaseNeeded, stable);
+ return holder.provider;
+ }
+
+ private final void incProviderRefLocked(ProviderRefCount prc, boolean stable) {
+ if (stable) {
+ prc.stableCount += 1;
+ if (prc.stableCount == 1) {
+ // We are acquiring a new stable reference on the provider.
+ int unstableDelta;
+ if (prc.removePending) {
+ // We have a pending remove operation, which is holding the
+ // last unstable reference. At this point we are converting
+ // that unstable reference to our new stable reference.
+ unstableDelta = -1;
+ // Cancel the removal of the provider.
+ if (DEBUG_PROVIDER) {
+ Slog.v(TAG, "incProviderRef: stable "
+ + "snatched provider from the jaws of death");
+ }
+ prc.removePending = false;
+ mH.removeMessages(H.REMOVE_PROVIDER, prc);
+ } else {
+ unstableDelta = 0;
+ }
+ try {
+ if (DEBUG_PROVIDER) {
+ Slog.v(TAG, "incProviderRef Now stable - "
+ + prc.holder.info.name + ": unstableDelta="
+ + unstableDelta);
+ }
+ ActivityManagerNative.getDefault().refContentProvider(
+ prc.holder.connection, 1, unstableDelta);
+ } catch (RemoteException e) {
+ //do nothing content provider object is dead any way
+ }
}
- try {
- ActivityManagerNative.getDefault().removeContentProvider(
- getApplicationThread(), name);
- } catch (RemoteException ex) {
+ } else {
+ prc.unstableCount += 1;
+ if (prc.unstableCount == 1) {
+ // We are acquiring a new unstable reference on the provider.
+ if (prc.removePending) {
+ // Oh look, we actually have a remove pending for the
+ // provider, which is still holding the last unstable
+ // reference. We just need to cancel that to take new
+ // ownership of the reference.
+ if (DEBUG_PROVIDER) {
+ Slog.v(TAG, "incProviderRef: unstable "
+ + "snatched provider from the jaws of death");
+ }
+ prc.removePending = false;
+ mH.removeMessages(H.REMOVE_PROVIDER, prc);
+ } else {
+ // First unstable ref, increment our count in the
+ // activity manager.
+ try {
+ if (DEBUG_PROVIDER) {
+ Slog.v(TAG, "incProviderRef: Now unstable - "
+ + prc.holder.info.name);
+ }
+ ActivityManagerNative.getDefault().refContentProvider(
+ prc.holder.connection, 0, 1);
+ } catch (RemoteException e) {
+ //do nothing content provider object is dead any way
+ }
+ }
}
}
- return provider;
}
- public final IContentProvider acquireExistingProvider(Context c, String name) {
+ public final IContentProvider acquireExistingProvider(Context c, String name,
+ boolean stable) {
synchronized (mProviderMap) {
ProviderClientRecord pr = mProviderMap.get(name);
if (pr == null) {
@@ -4232,23 +4313,14 @@ public final class ActivityThread {
// provider is not reference counted and never needs to be released.
ProviderRefCount prc = mProviderRefCountMap.get(jBinder);
if (prc != null) {
- prc.count += 1;
- if (prc.count == 1) {
- if (localLOGV) {
- Slog.v(TAG, "acquireExistingProvider: "
- + "snatched provider from the jaws of death");
- }
- // Because the provider previously had a reference count of zero,
- // it was scheduled to be removed. Cancel that.
- mH.removeMessages(H.REMOVE_PROVIDER, provider);
- }
+ incProviderRefLocked(prc, stable);
}
return provider;
}
}
- public final boolean releaseProvider(IContentProvider provider) {
- if(provider == null) {
+ public final boolean releaseProvider(IContentProvider provider, boolean stable) {
+ if (provider == null) {
return false;
}
@@ -4260,55 +4332,98 @@ public final class ActivityThread {
return false;
}
- if (prc.count == 0) {
- if (localLOGV) Slog.v(TAG, "releaseProvider: ref count already 0, how?");
- return false;
+ boolean lastRef = false;
+ if (stable) {
+ if (prc.stableCount == 0) {
+ if (DEBUG_PROVIDER) Slog.v(TAG,
+ "releaseProvider: stable ref count already 0, how?");
+ return false;
+ }
+ prc.stableCount -= 1;
+ if (prc.stableCount == 0) {
+ // What we do at this point depends on whether there are
+ // any unstable refs left: if there are, we just tell the
+ // activity manager to decrement its stable count; if there
+ // aren't, we need to enqueue this provider to be removed,
+ // and convert to holding a single unstable ref while
+ // doing so.
+ lastRef = prc.unstableCount == 0;
+ try {
+ if (DEBUG_PROVIDER) {
+ Slog.v(TAG, "releaseProvider: No longer stable w/lastRef="
+ + lastRef + " - " + prc.holder.info.name);
+ }
+ ActivityManagerNative.getDefault().refContentProvider(
+ prc.holder.connection, -1, lastRef ? 1 : 0);
+ } catch (RemoteException e) {
+ //do nothing content provider object is dead any way
+ }
+ }
+ } else {
+ if (prc.unstableCount == 0) {
+ if (DEBUG_PROVIDER) Slog.v(TAG,
+ "releaseProvider: unstable ref count already 0, how?");
+ return false;
+ }
+ prc.unstableCount -= 1;
+ if (prc.unstableCount == 0) {
+ // If this is the last reference, we need to enqueue
+ // this provider to be removed instead of telling the
+ // activity manager to remove it at this point.
+ lastRef = prc.stableCount == 0;
+ if (!lastRef) {
+ try {
+ if (DEBUG_PROVIDER) {
+ Slog.v(TAG, "releaseProvider: No longer unstable - "
+ + prc.holder.info.name);
+ }
+ ActivityManagerNative.getDefault().refContentProvider(
+ prc.holder.connection, 0, -1);
+ } catch (RemoteException e) {
+ //do nothing content provider object is dead any way
+ }
+ }
+ }
}
- prc.count -= 1;
- if (prc.count == 0) {
- // Schedule the actual remove asynchronously, since we don't know the context
- // this will be called in.
- // TODO: it would be nice to post a delayed message, so
- // if we come back and need the same provider quickly
- // we will still have it available.
- Message msg = mH.obtainMessage(H.REMOVE_PROVIDER, provider);
- mH.sendMessage(msg);
+ if (lastRef) {
+ if (!prc.removePending) {
+ // Schedule the actual remove asynchronously, since we don't know the context
+ // this will be called in.
+ // TODO: it would be nice to post a delayed message, so
+ // if we come back and need the same provider quickly
+ // we will still have it available.
+ if (DEBUG_PROVIDER) {
+ Slog.v(TAG, "releaseProvider: Enqueueing pending removal - "
+ + prc.holder.info.name);
+ }
+ prc.removePending = true;
+ Message msg = mH.obtainMessage(H.REMOVE_PROVIDER, prc);
+ mH.sendMessage(msg);
+ } else {
+ Slog.w(TAG, "Duplicate remove pending of provider " + prc.holder.info.name);
+ }
}
return true;
}
}
- public final IContentProvider acquireUnstableProvider(Context c, String name) {
- return acquireProvider(c, name);
- }
-
- public final boolean releaseUnstableProvider(IContentProvider provider) {
- return releaseProvider(provider);
- }
-
- final void completeRemoveProvider(IContentProvider provider) {
- IBinder jBinder = provider.asBinder();
- String remoteProviderName = null;
- synchronized(mProviderMap) {
- ProviderRefCount prc = mProviderRefCountMap.get(jBinder);
- if (prc == null) {
- // Either no release is needed (so we shouldn't be here) or the
- // provider was already released.
- if (localLOGV) Slog.v(TAG, "completeRemoveProvider: release not needed");
- return;
- }
-
- if (prc.count != 0) {
+ final void completeRemoveProvider(ProviderRefCount prc) {
+ synchronized (mProviderMap) {
+ if (!prc.removePending) {
// There was a race! Some other client managed to acquire
// the provider before the removal was completed.
// Abort the removal. We will do it later.
- if (localLOGV) Slog.v(TAG, "completeRemoveProvider: lost the race, "
+ if (DEBUG_PROVIDER) Slog.v(TAG, "completeRemoveProvider: lost the race, "
+ "provider still in use");
return;
}
- mProviderRefCountMap.remove(jBinder);
+ final IBinder jBinder = prc.holder.provider.asBinder();
+ ProviderRefCount existingPrc = mProviderRefCountMap.get(jBinder);
+ if (existingPrc == prc) {
+ mProviderRefCountMap.remove(jBinder);
+ }
Iterator<ProviderClientRecord> iter = mProviderMap.values().iterator();
while (iter.hasNext()) {
@@ -4316,41 +4431,70 @@ public final class ActivityThread {
IBinder myBinder = pr.mProvider.asBinder();
if (myBinder == jBinder) {
iter.remove();
- if (pr.mLocalProvider == null) {
- myBinder.unlinkToDeath(pr, 0);
- if (remoteProviderName == null) {
- remoteProviderName = pr.mName;
- }
- }
}
}
}
- if (remoteProviderName != null) {
- try {
- if (localLOGV) {
- Slog.v(TAG, "removeProvider: Invoking ActivityManagerNative."
- + "removeContentProvider(" + remoteProviderName + ")");
- }
- ActivityManagerNative.getDefault().removeContentProvider(
- getApplicationThread(), remoteProviderName);
- } catch (RemoteException e) {
- //do nothing content provider object is dead any way
+ try {
+ if (DEBUG_PROVIDER) {
+ Slog.v(TAG, "removeProvider: Invoking ActivityManagerNative."
+ + "removeContentProvider(" + prc.holder.info.name + ")");
}
+ ActivityManagerNative.getDefault().removeContentProvider(
+ prc.holder.connection, false);
+ } catch (RemoteException e) {
+ //do nothing content provider object is dead any way
}
}
- final void removeDeadProvider(String name, IContentProvider provider) {
+ final void handleUnstableProviderDied(IBinder provider, boolean fromClient) {
synchronized(mProviderMap) {
- ProviderClientRecord pr = mProviderMap.get(name);
- if (pr != null && pr.mProvider.asBinder() == provider.asBinder()) {
- Slog.i(TAG, "Removing dead content provider: " + name);
- ProviderClientRecord removed = mProviderMap.remove(name);
- if (removed != null) {
- removed.mProvider.asBinder().unlinkToDeath(removed, 0);
+ ProviderRefCount prc = mProviderRefCountMap.get(provider);
+ if (prc != null) {
+ if (DEBUG_PROVIDER) Slog.v(TAG, "Cleaning up dead provider "
+ + provider + " " + prc.holder.info.name);
+ mProviderRefCountMap.remove(provider);
+ if (prc.client != null && prc.client.mNames != null) {
+ for (String name : prc.client.mNames) {
+ ProviderClientRecord pr = mProviderMap.get(name);
+ if (pr != null && pr.mProvider.asBinder() == provider) {
+ Slog.i(TAG, "Removing dead content provider: " + name);
+ mProviderMap.remove(name);
+ }
+ }
}
+ if (fromClient) {
+ // We found out about this due to execution in our client
+ // code. Tell the activity manager about it now, to ensure
+ // that the next time we go to do anything with the provider
+ // it knows it is dead (so we don't race with its death
+ // notification).
+ try {
+ ActivityManagerNative.getDefault().unstableProviderDied(
+ prc.holder.connection);
+ } catch (RemoteException e) {
+ //do nothing content provider object is dead any way
+ }
+ }
+ }
+ }
+ }
+
+ private ProviderClientRecord installProviderAuthoritiesLocked(IContentProvider provider,
+ ContentProvider localProvider,IActivityManager.ContentProviderHolder holder) {
+ String names[] = PATTERN_SEMICOLON.split(holder.info.authority);
+ ProviderClientRecord pcr = new ProviderClientRecord(names, provider,
+ localProvider, holder);
+ for (int i = 0; i < names.length; i++) {
+ ProviderClientRecord existing = mProviderMap.get(names[i]);
+ if (existing != null) {
+ Slog.w(TAG, "Content provider " + pcr.mHolder.info.name
+ + " already published as " + names[i]);
+ } else {
+ mProviderMap.put(names[i], pcr);
}
}
+ return pcr;
}
/**
@@ -4367,12 +4511,13 @@ public final class ActivityThread {
* and returns the existing provider. This can happen due to concurrent
* attempts to acquire the same provider.
*/
- private IContentProvider installProvider(Context context,
- IContentProvider provider, ProviderInfo info,
- boolean noisy, boolean noReleaseNeeded) {
+ private IActivityManager.ContentProviderHolder installProvider(Context context,
+ IActivityManager.ContentProviderHolder holder, ProviderInfo info,
+ boolean noisy, boolean noReleaseNeeded, boolean stable) {
ContentProvider localProvider = null;
- if (provider == null) {
- if (noisy) {
+ IContentProvider provider;
+ if (holder == null || holder.provider == null) {
+ if (DEBUG_PROVIDER || noisy) {
Slog.d(TAG, "Loading provider " + info.authority + ": "
+ info.name);
}
@@ -4409,7 +4554,7 @@ public final class ActivityThread {
info.applicationInfo.sourceDir);
return null;
}
- if (false) Slog.v(
+ if (DEBUG_PROVIDER) Slog.v(
TAG, "Instantiating local provider " + info.name);
// XXX Need to create the correct context for this provider.
localProvider.attachInfo(c, info);
@@ -4421,76 +4566,72 @@ public final class ActivityThread {
}
return null;
}
- } else if (localLOGV) {
- Slog.v(TAG, "Installing external provider " + info.authority + ": "
+ } else {
+ provider = holder.provider;
+ if (DEBUG_PROVIDER) Slog.v(TAG, "Installing external provider " + info.authority + ": "
+ info.name);
}
+ IActivityManager.ContentProviderHolder retHolder;
+
synchronized (mProviderMap) {
- // There is a possibility that this thread raced with another thread to
- // add the provider. If we find another thread got there first then we
- // just get out of the way and return the original provider.
+ if (DEBUG_PROVIDER) Slog.v(TAG, "Checking to add " + provider
+ + " / " + info.name);
IBinder jBinder = provider.asBinder();
- String names[] = PATTERN_SEMICOLON.split(info.authority);
- for (int i = 0; i < names.length; i++) {
- ProviderClientRecord pr = mProviderMap.get(names[i]);
- if (pr != null) {
- if (localLOGV) {
- Slog.v(TAG, "installProvider: lost the race, "
- + "using existing named provider");
- }
- provider = pr.mProvider;
- } else {
- pr = new ProviderClientRecord(names[i], provider, localProvider);
- if (localProvider == null) {
- try {
- jBinder.linkToDeath(pr, 0);
- } catch (RemoteException e) {
- // Provider already dead. Bail out of here without making
- // any changes to the provider map or other data structures.
- return null;
- }
- }
- mProviderMap.put(names[i], pr);
- }
- }
-
if (localProvider != null) {
- ProviderClientRecord pr = mLocalProviders.get(jBinder);
+ ComponentName cname = new ComponentName(info.packageName, info.name);
+ ProviderClientRecord pr = mLocalProvidersByName.get(cname);
if (pr != null) {
- if (localLOGV) {
+ if (DEBUG_PROVIDER) {
Slog.v(TAG, "installProvider: lost the race, "
+ "using existing local provider");
}
provider = pr.mProvider;
} else {
- pr = new ProviderClientRecord(null, provider, localProvider);
+ holder = new IActivityManager.ContentProviderHolder(info);
+ holder.provider = provider;
+ holder.noReleaseNeeded = true;
+ pr = installProviderAuthoritiesLocked(provider, localProvider, holder);
mLocalProviders.put(jBinder, pr);
+ mLocalProvidersByName.put(cname, pr);
}
- }
-
- if (!noReleaseNeeded) {
+ retHolder = pr.mHolder;
+ } else {
ProviderRefCount prc = mProviderRefCountMap.get(jBinder);
if (prc != null) {
- if (localLOGV) {
- Slog.v(TAG, "installProvider: lost the race, incrementing ref count");
+ if (DEBUG_PROVIDER) {
+ Slog.v(TAG, "installProvider: lost the race, updating ref count");
}
- prc.count += 1;
- if (prc.count == 1) {
- if (localLOGV) {
- Slog.v(TAG, "installProvider: "
- + "snatched provider from the jaws of death");
+ // We need to transfer our new reference to the existing
+ // ref count, releasing the old one... but only if
+ // release is needed (that is, it is not running in the
+ // system process).
+ if (!noReleaseNeeded) {
+ incProviderRefLocked(prc, stable);
+ try {
+ ActivityManagerNative.getDefault().removeContentProvider(
+ holder.connection, stable);
+ } catch (RemoteException e) {
+ //do nothing content provider object is dead any way
}
- // Because the provider previously had a reference count of zero,
- // it was scheduled to be removed. Cancel that.
- mH.removeMessages(H.REMOVE_PROVIDER, provider);
}
} else {
- mProviderRefCountMap.put(jBinder, new ProviderRefCount(1));
+ ProviderClientRecord client = installProviderAuthoritiesLocked(
+ provider, localProvider, holder);
+ if (noReleaseNeeded) {
+ prc = new ProviderRefCount(holder, client, 1000, 1000);
+ } else {
+ prc = stable
+ ? new ProviderRefCount(holder, client, 1, 0)
+ : new ProviderRefCount(holder, client, 0, 1);
+ }
+ mProviderRefCountMap.put(jBinder, prc);
}
+ retHolder = prc.holder;
}
}
- return provider;
+
+ return retHolder;
}
private void attach(boolean system) {
diff --git a/core/java/android/app/ApplicationThreadNative.java b/core/java/android/app/ApplicationThreadNative.java
index 437362b..3e726e0 100644
--- a/core/java/android/app/ApplicationThreadNative.java
+++ b/core/java/android/app/ApplicationThreadNative.java
@@ -575,6 +575,15 @@ public abstract class ApplicationThreadNative extends Binder
reply.writeNoException();
return true;
}
+
+ case UNSTABLE_PROVIDER_DIED_TRANSACTION:
+ {
+ data.enforceInterface(IApplicationThread.descriptor);
+ IBinder provider = data.readStrongBinder();
+ unstableProviderDied(provider);
+ reply.writeNoException();
+ return true;
+ }
}
return super.onTransact(code, data, reply, flags);
@@ -1163,4 +1172,12 @@ class ApplicationThreadProxy implements IApplicationThread {
mRemote.transact(DUMP_DB_INFO_TRANSACTION, data, null, IBinder.FLAG_ONEWAY);
data.recycle();
}
+
+ public void unstableProviderDied(IBinder provider) throws RemoteException {
+ Parcel data = Parcel.obtain();
+ data.writeInterfaceToken(IApplicationThread.descriptor);
+ data.writeStrongBinder(provider);
+ mRemote.transact(UNSTABLE_PROVIDER_DIED_TRANSACTION, data, null, IBinder.FLAG_ONEWAY);
+ data.recycle();
+ }
}
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java
index 299e408..4c35a8c 100644
--- a/core/java/android/app/ContextImpl.java
+++ b/core/java/android/app/ContextImpl.java
@@ -1679,27 +1679,32 @@ class ContextImpl extends Context {
@Override
protected IContentProvider acquireProvider(Context context, String name) {
- return mMainThread.acquireProvider(context, name);
+ return mMainThread.acquireProvider(context, name, true);
}
@Override
protected IContentProvider acquireExistingProvider(Context context, String name) {
- return mMainThread.acquireExistingProvider(context, name);
+ return mMainThread.acquireExistingProvider(context, name, true);
}
@Override
public boolean releaseProvider(IContentProvider provider) {
- return mMainThread.releaseProvider(provider);
+ return mMainThread.releaseProvider(provider, true);
}
@Override
protected IContentProvider acquireUnstableProvider(Context c, String name) {
- return mMainThread.acquireUnstableProvider(c, name);
+ return mMainThread.acquireProvider(c, name, false);
}
@Override
public boolean releaseUnstableProvider(IContentProvider icp) {
- return mMainThread.releaseUnstableProvider(icp);
+ return mMainThread.releaseProvider(icp, false);
+ }
+
+ @Override
+ public void unstableProviderDied(IContentProvider icp) {
+ mMainThread.handleUnstableProviderDied(icp.asBinder(), true);
}
private final ActivityThread mMainThread;
diff --git a/core/java/android/app/FragmentManager.java b/core/java/android/app/FragmentManager.java
index 6058bdc..03ee419 100644
--- a/core/java/android/app/FragmentManager.java
+++ b/core/java/android/app/FragmentManager.java
@@ -1568,8 +1568,17 @@ final class FragmentManagerImpl extends FragmentManager {
for (int i=0; i<N; i++) {
Fragment f = mActive.get(i);
if (f != null) {
+ if (f.mIndex < 0) {
+ String msg = "Failure saving state: active " + f
+ + " has cleared index: " + f.mIndex;
+ Slog.e(TAG, msg);
+ dump(" ", null, new PrintWriter(new LogWriter(
+ Log.ERROR, TAG, Log.LOG_ID_SYSTEM)), new String[] { });
+ throw new IllegalStateException(msg);
+ }
+
haveFragments = true;
-
+
FragmentState fs = new FragmentState(f);
active[i] = fs;
@@ -1621,6 +1630,14 @@ final class FragmentManagerImpl extends FragmentManager {
added = new int[N];
for (int i=0; i<N; i++) {
added[i] = mAdded.get(i).mIndex;
+ if (added[i] < 0) {
+ String msg = "Failure saving state: active " + mAdded.get(i)
+ + " has cleared index: " + added[i];
+ Slog.e(TAG, msg);
+ dump(" ", null, new PrintWriter(new LogWriter(
+ Log.ERROR, TAG, Log.LOG_ID_SYSTEM)), new String[] { });
+ throw new IllegalStateException(msg);
+ }
if (DEBUG) Log.v(TAG, "saveAllState: adding fragment #" + i
+ ": " + mAdded.get(i));
}
diff --git a/core/java/android/app/IActivityManager.java b/core/java/android/app/IActivityManager.java
index cf304df..609a047 100644
--- a/core/java/android/app/IActivityManager.java
+++ b/core/java/android/app/IActivityManager.java
@@ -116,14 +116,16 @@ public interface IActivityManager extends IInterface {
public void reportThumbnail(IBinder token,
Bitmap thumbnail, CharSequence description) throws RemoteException;
public ContentProviderHolder getContentProvider(IApplicationThread caller,
- String name) throws RemoteException;
+ String name, boolean stable) throws RemoteException;
public ContentProviderHolder getContentProviderExternal(String name, IBinder token)
throws RemoteException;
- public void removeContentProvider(IApplicationThread caller,
- String name) throws RemoteException;
+ public void removeContentProvider(IBinder connection, boolean stable) throws RemoteException;
public void removeContentProviderExternal(String name, IBinder token) throws RemoteException;
public void publishContentProviders(IApplicationThread caller,
List<ContentProviderHolder> providers) throws RemoteException;
+ public boolean refContentProvider(IBinder connection, int stableDelta, int unstableDelta)
+ throws RemoteException;
+ public void unstableProviderDied(IBinder connection) throws RemoteException;
public PendingIntent getRunningServiceControlPanel(ComponentName service)
throws RemoteException;
public ComponentName startService(IApplicationThread caller, Intent service,
@@ -363,6 +365,7 @@ public interface IActivityManager extends IInterface {
public static class ContentProviderHolder implements Parcelable {
public final ProviderInfo info;
public IContentProvider provider;
+ public IBinder connection;
public boolean noReleaseNeeded;
public ContentProviderHolder(ProviderInfo _info) {
@@ -380,6 +383,7 @@ public interface IActivityManager extends IInterface {
} else {
dest.writeStrongBinder(null);
}
+ dest.writeStrongBinder(connection);
dest.writeInt(noReleaseNeeded ? 1:0);
}
@@ -398,6 +402,7 @@ public interface IActivityManager extends IInterface {
info = ProviderInfo.CREATOR.createFromParcel(source);
provider = ContentProviderNative.asInterface(
source.readStrongBinder());
+ connection = source.readStrongBinder();
noReleaseNeeded = source.readInt() != 0;
}
}
@@ -476,7 +481,7 @@ public interface IActivityManager extends IInterface {
int REPORT_THUMBNAIL_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+27;
int GET_CONTENT_PROVIDER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+28;
int PUBLISH_CONTENT_PROVIDERS_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+29;
-
+ int REF_CONTENT_PROVIDER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+30;
int FINISH_SUB_ACTIVITY_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+31;
int GET_RUNNING_SERVICE_CONTROL_PANEL_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+32;
int START_SERVICE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+33;
@@ -597,4 +602,5 @@ public interface IActivityManager extends IInterface {
int SET_LOCK_SCREEN_SHOWN_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+147;
int FINISH_ACTIVITY_AFFINITY_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+148;
int GET_LAUNCHED_FROM_UID_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+149;
+ int UNSTABLE_PROVIDER_DIED_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+150;
}
diff --git a/core/java/android/app/IApplicationThread.java b/core/java/android/app/IApplicationThread.java
index 70029d2..f60cfd6 100644
--- a/core/java/android/app/IApplicationThread.java
+++ b/core/java/android/app/IApplicationThread.java
@@ -128,6 +128,7 @@ public interface IApplicationThread extends IInterface {
String[] args) throws RemoteException;
void dumpGfxInfo(FileDescriptor fd, String[] args) throws RemoteException;
void dumpDbInfo(FileDescriptor fd, String[] args) throws RemoteException;
+ void unstableProviderDied(IBinder provider) throws RemoteException;
String descriptor = "android.app.IApplicationThread";
@@ -176,4 +177,5 @@ public interface IApplicationThread extends IInterface {
int DUMP_GFX_INFO_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+43;
int DUMP_PROVIDER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+44;
int DUMP_DB_INFO_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+45;
+ int UNSTABLE_PROVIDER_DIED_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+46;
}
diff --git a/core/java/android/app/Instrumentation.java b/core/java/android/app/Instrumentation.java
index 75c6e11..cad4b01 100644
--- a/core/java/android/app/Instrumentation.java
+++ b/core/java/android/app/Instrumentation.java
@@ -987,7 +987,12 @@ public class Instrumentation {
/**
* Perform calling of the application's {@link Application#onCreate}
* method. The default implementation simply calls through to that method.
- *
+ *
+ * <p>Note: This method will be called immediately after {@link #onCreate(Bundle)}.
+ * Often instrumentation tests start their test thread in onCreate(); you
+ * need to be careful of races between these. (Well between it and
+ * everything else, but let's start here.)
+ *
* @param app The application being created.
*/
public void callApplicationOnCreate(Application app) {
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index 3ced82b..036008b 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -1379,7 +1379,7 @@ public class Notification implements Parcelable
}
}
- private RemoteViews applyStandardTemplate(int resId) {
+ private RemoteViews applyStandardTemplate(int resId, boolean fitIn1U) {
RemoteViews contentView = new RemoteViews(mContext.getPackageName(), resId);
boolean showLine3 = false;
boolean showLine2 = false;
@@ -1432,7 +1432,6 @@ public class Notification implements Parcelable
contentView.setTextViewText(R.id.text, mSubText);
if (mContentText != null) {
contentView.setTextViewText(R.id.text2, mContentText);
- // need to shrink all the type to make sure everything fits
contentView.setViewVisibility(R.id.text2, View.VISIBLE);
showLine2 = true;
} else {
@@ -1450,10 +1449,13 @@ public class Notification implements Parcelable
}
}
if (showLine2) {
- final Resources res = mContext.getResources();
- final float subTextSize = res.getDimensionPixelSize(
- R.dimen.notification_subtext_size);
- contentView.setTextViewTextSize(R.id.text, TypedValue.COMPLEX_UNIT_PX, subTextSize);
+ if (fitIn1U) {
+ // need to shrink all the type to make sure everything fits
+ final Resources res = mContext.getResources();
+ final float subTextSize = res.getDimensionPixelSize(
+ R.dimen.notification_subtext_size);
+ contentView.setTextViewTextSize(R.id.text, TypedValue.COMPLEX_UNIT_PX, subTextSize);
+ }
// vertical centering
contentView.setViewPadding(R.id.line1, 0, 0, 0, 0);
}
@@ -1470,16 +1472,18 @@ public class Notification implements Parcelable
}
}
contentView.setViewVisibility(R.id.line3, showLine3 ? View.VISIBLE : View.GONE);
+ contentView.setViewVisibility(R.id.overflow_divider, showLine3 ? View.VISIBLE : View.GONE);
return contentView;
}
private RemoteViews applyStandardTemplateWithActions(int layoutId) {
- RemoteViews big = applyStandardTemplate(layoutId);
+ RemoteViews big = applyStandardTemplate(layoutId, false);
int N = mActions.size();
if (N > 0) {
// Log.d("Notification", "has actions: " + mContentText);
big.setViewVisibility(R.id.actions, View.VISIBLE);
+ big.setViewVisibility(R.id.action_divider, View.VISIBLE);
if (N>MAX_ACTION_BUTTONS) N=MAX_ACTION_BUTTONS;
big.removeAllViews(R.id.actions);
for (int i=0; i<N; i++) {
@@ -1495,7 +1499,7 @@ public class Notification implements Parcelable
if (mContentView != null) {
return mContentView;
} else {
- return applyStandardTemplate(R.layout.notification_template_base); // no more special large_icon flavor
+ return applyStandardTemplate(R.layout.notification_template_base, true); // no more special large_icon flavor
}
}
@@ -1506,7 +1510,7 @@ public class Notification implements Parcelable
if (mContentView == null) {
return applyStandardTemplate(mLargeIcon == null
? R.layout.status_bar_latest_event_ticker
- : R.layout.status_bar_latest_event_ticker_large_icon);
+ : R.layout.status_bar_latest_event_ticker_large_icon, true);
} else {
return null;
}
@@ -1655,12 +1659,9 @@ public class Notification implements Parcelable
contentView.setViewVisibility(R.id.line1, View.VISIBLE);
}
+ // The last line defaults to the content text or subtext, but can be replaced by mSummaryText
if (mSummaryText != null && !mSummaryText.equals("")) {
- contentView.setViewVisibility(R.id.overflow_title, View.VISIBLE);
- contentView.setTextViewText(R.id.overflow_title, mSummaryText);
- contentView.setViewVisibility(R.id.line3, View.GONE);
- } else {
- contentView.setViewVisibility(R.id.overflow_title, View.GONE);
+ contentView.setTextViewText(R.id.text, mSummaryText);
contentView.setViewVisibility(R.id.line3, View.VISIBLE);
}
@@ -1801,6 +1802,8 @@ public class Notification implements Parcelable
}
private RemoteViews makeBigContentView() {
+ // Remove the content text so line3 disappears entirely
+ mBuilder.mContentText = null;
RemoteViews contentView = getStandardView(R.layout.notification_template_big_text);
contentView.setTextViewText(R.id.big_text, mBigText);
contentView.setViewVisibility(R.id.big_text, View.VISIBLE);
diff --git a/core/java/android/app/backup/BackupManager.java b/core/java/android/app/backup/BackupManager.java
index 6eebed2..be8108c 100644
--- a/core/java/android/app/backup/BackupManager.java
+++ b/core/java/android/app/backup/BackupManager.java
@@ -145,8 +145,10 @@ public class BackupManager {
try {
IRestoreSession binder = sService.beginRestoreSession(mContext.getPackageName(),
null);
- session = new RestoreSession(mContext, binder);
- result = session.restorePackage(mContext.getPackageName(), observer);
+ if (binder != null) {
+ session = new RestoreSession(mContext, binder);
+ result = session.restorePackage(mContext.getPackageName(), observer);
+ }
} catch (RemoteException e) {
Log.w(TAG, "restoreSelf() unable to contact service");
} finally {
@@ -170,7 +172,9 @@ public class BackupManager {
try {
// All packages, current transport
IRestoreSession binder = sService.beginRestoreSession(null, null);
- session = new RestoreSession(mContext, binder);
+ if (binder != null) {
+ session = new RestoreSession(mContext, binder);
+ }
} catch (RemoteException e) {
Log.w(TAG, "beginRestoreSession() couldn't connect");
}
diff --git a/core/java/android/content/ContentProviderClient.java b/core/java/android/content/ContentProviderClient.java
index 423f1f6..5c315ce 100644
--- a/core/java/android/content/ContentProviderClient.java
+++ b/core/java/android/content/ContentProviderClient.java
@@ -20,6 +20,7 @@ import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.os.CancellationSignal;
+import android.os.DeadObjectException;
import android.os.ICancellationSignal;
import android.os.RemoteException;
import android.os.ParcelFileDescriptor;
@@ -33,11 +34,19 @@ import java.util.ArrayList;
* calling {@link ContentResolver#acquireContentProviderClient}. This object must be released
* using {@link #release} in order to indicate to the system that the {@link ContentProvider} is
* no longer needed and can be killed to free up resources.
+ *
+ * <p>Note that you should generally create a new ContentProviderClient instance
+ * for each thread that will be performing operations. Unlike
+ * {@link ContentResolver}, the methods here such as {@link #query} and
+ * {@link #openFile} are not thread safe -- you must not call
+ * {@link #release()} on the ContentProviderClient those calls are made from
+ * until you are finished with the data they have returned.
*/
public class ContentProviderClient {
private final IContentProvider mContentProvider;
private final ContentResolver mContentResolver;
private final boolean mStable;
+ private boolean mReleased;
/**
* @hide
@@ -52,7 +61,14 @@ public class ContentProviderClient {
/** See {@link ContentProvider#query ContentProvider.query} */
public Cursor query(Uri url, String[] projection, String selection,
String[] selectionArgs, String sortOrder) throws RemoteException {
- return query(url, projection, selection, selectionArgs, sortOrder, null);
+ try {
+ return query(url, projection, selection, selectionArgs, sortOrder, null);
+ } catch (DeadObjectException e) {
+ if (!mStable) {
+ mContentResolver.unstableProviderDied(mContentProvider);
+ }
+ throw e;
+ }
}
/** See {@link ContentProvider#query ContentProvider.query} */
@@ -64,41 +80,90 @@ public class ContentProviderClient {
remoteCancellationSignal = mContentProvider.createCancellationSignal();
cancellationSignal.setRemote(remoteCancellationSignal);
}
- return mContentProvider.query(url, projection, selection, selectionArgs, sortOrder,
- remoteCancellationSignal);
+ try {
+ return mContentProvider.query(url, projection, selection, selectionArgs, sortOrder,
+ remoteCancellationSignal);
+ } catch (DeadObjectException e) {
+ if (!mStable) {
+ mContentResolver.unstableProviderDied(mContentProvider);
+ }
+ throw e;
+ }
}
/** See {@link ContentProvider#getType ContentProvider.getType} */
public String getType(Uri url) throws RemoteException {
- return mContentProvider.getType(url);
+ try {
+ return mContentProvider.getType(url);
+ } catch (DeadObjectException e) {
+ if (!mStable) {
+ mContentResolver.unstableProviderDied(mContentProvider);
+ }
+ throw e;
+ }
}
/** See {@link ContentProvider#getStreamTypes ContentProvider.getStreamTypes} */
public String[] getStreamTypes(Uri url, String mimeTypeFilter) throws RemoteException {
- return mContentProvider.getStreamTypes(url, mimeTypeFilter);
+ try {
+ return mContentProvider.getStreamTypes(url, mimeTypeFilter);
+ } catch (DeadObjectException e) {
+ if (!mStable) {
+ mContentResolver.unstableProviderDied(mContentProvider);
+ }
+ throw e;
+ }
}
/** See {@link ContentProvider#insert ContentProvider.insert} */
public Uri insert(Uri url, ContentValues initialValues)
throws RemoteException {
- return mContentProvider.insert(url, initialValues);
+ try {
+ return mContentProvider.insert(url, initialValues);
+ } catch (DeadObjectException e) {
+ if (!mStable) {
+ mContentResolver.unstableProviderDied(mContentProvider);
+ }
+ throw e;
+ }
}
/** See {@link ContentProvider#bulkInsert ContentProvider.bulkInsert} */
public int bulkInsert(Uri url, ContentValues[] initialValues) throws RemoteException {
- return mContentProvider.bulkInsert(url, initialValues);
+ try {
+ return mContentProvider.bulkInsert(url, initialValues);
+ } catch (DeadObjectException e) {
+ if (!mStable) {
+ mContentResolver.unstableProviderDied(mContentProvider);
+ }
+ throw e;
+ }
}
/** See {@link ContentProvider#delete ContentProvider.delete} */
public int delete(Uri url, String selection, String[] selectionArgs)
throws RemoteException {
- return mContentProvider.delete(url, selection, selectionArgs);
+ try {
+ return mContentProvider.delete(url, selection, selectionArgs);
+ } catch (DeadObjectException e) {
+ if (!mStable) {
+ mContentResolver.unstableProviderDied(mContentProvider);
+ }
+ throw e;
+ }
}
/** See {@link ContentProvider#update ContentProvider.update} */
public int update(Uri url, ContentValues values, String selection,
String[] selectionArgs) throws RemoteException {
- return mContentProvider.update(url, values, selection, selectionArgs);
+ try {
+ return mContentProvider.update(url, values, selection, selectionArgs);
+ } catch (DeadObjectException e) {
+ if (!mStable) {
+ mContentResolver.unstableProviderDied(mContentProvider);
+ }
+ throw e;
+ }
}
/**
@@ -110,7 +175,14 @@ public class ContentProviderClient {
*/
public ParcelFileDescriptor openFile(Uri url, String mode)
throws RemoteException, FileNotFoundException {
- return mContentProvider.openFile(url, mode);
+ try {
+ return mContentProvider.openFile(url, mode);
+ } catch (DeadObjectException e) {
+ if (!mStable) {
+ mContentResolver.unstableProviderDied(mContentProvider);
+ }
+ throw e;
+ }
}
/**
@@ -122,20 +194,41 @@ public class ContentProviderClient {
*/
public AssetFileDescriptor openAssetFile(Uri url, String mode)
throws RemoteException, FileNotFoundException {
- return mContentProvider.openAssetFile(url, mode);
+ try {
+ return mContentProvider.openAssetFile(url, mode);
+ } catch (DeadObjectException e) {
+ if (!mStable) {
+ mContentResolver.unstableProviderDied(mContentProvider);
+ }
+ throw e;
+ }
}
/** See {@link ContentProvider#openTypedAssetFile ContentProvider.openTypedAssetFile} */
public final AssetFileDescriptor openTypedAssetFileDescriptor(Uri uri,
String mimeType, Bundle opts)
throws RemoteException, FileNotFoundException {
- return mContentProvider.openTypedAssetFile(uri, mimeType, opts);
+ try {
+ return mContentProvider.openTypedAssetFile(uri, mimeType, opts);
+ } catch (DeadObjectException e) {
+ if (!mStable) {
+ mContentResolver.unstableProviderDied(mContentProvider);
+ }
+ throw e;
+ }
}
/** See {@link ContentProvider#applyBatch ContentProvider.applyBatch} */
public ContentProviderResult[] applyBatch(ArrayList<ContentProviderOperation> operations)
throws RemoteException, OperationApplicationException {
- return mContentProvider.applyBatch(operations);
+ try {
+ return mContentProvider.applyBatch(operations);
+ } catch (DeadObjectException e) {
+ if (!mStable) {
+ mContentResolver.unstableProviderDied(mContentProvider);
+ }
+ throw e;
+ }
}
/**
@@ -144,10 +237,16 @@ public class ContentProviderClient {
* @return true if this was release, false if it was already released
*/
public boolean release() {
- if (mStable) {
- return mContentResolver.releaseProvider(mContentProvider);
- } else {
- return mContentResolver.releaseUnstableProvider(mContentProvider);
+ synchronized (this) {
+ if (mReleased) {
+ throw new IllegalStateException("Already released");
+ }
+ mReleased = true;
+ if (mStable) {
+ return mContentResolver.releaseProvider(mContentProvider);
+ } else {
+ return mContentResolver.releaseUnstableProvider(mContentProvider);
+ }
}
}
diff --git a/core/java/android/content/ContentResolver.java b/core/java/android/content/ContentResolver.java
index f509fd8..34b5a30 100644
--- a/core/java/android/content/ContentResolver.java
+++ b/core/java/android/content/ContentResolver.java
@@ -20,27 +20,24 @@ import dalvik.system.CloseGuard;
import android.accounts.Account;
import android.app.ActivityManagerNative;
-import android.app.ActivityThread;
import android.app.AppGlobals;
-import android.content.ContentProvider.Transport;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.res.AssetFileDescriptor;
import android.content.res.Resources;
import android.database.ContentObserver;
import android.database.CrossProcessCursorWrapper;
import android.database.Cursor;
-import android.database.CursorWrapper;
import android.database.IContentObserver;
import android.net.Uri;
import android.os.Bundle;
import android.os.CancellationSignal;
+import android.os.DeadObjectException;
import android.os.IBinder;
import android.os.ICancellationSignal;
import android.os.OperationCanceledException;
import android.os.ParcelFileDescriptor;
import android.os.RemoteException;
import android.os.ServiceManager;
-import android.os.StrictMode;
import android.os.SystemClock;
import android.text.TextUtils;
import android.util.EventLog;
@@ -202,6 +199,8 @@ public abstract class ContentResolver {
protected abstract IContentProvider acquireUnstableProvider(Context c, String name);
/** @hide */
public abstract boolean releaseUnstableProvider(IContentProvider icp);
+ /** @hide */
+ public abstract void unstableProviderDied(IContentProvider icp);
/**
* Return the MIME type of the given content URL.
@@ -211,6 +210,7 @@ public abstract class ContentResolver {
* @return A MIME type for the content, or null if the URL is invalid or the type is unknown
*/
public final String getType(Uri url) {
+ // XXX would like to have an acquireExistingUnstableProvider for this.
IContentProvider provider = acquireExistingProvider(url);
if (provider != null) {
try {
@@ -351,23 +351,37 @@ public abstract class ContentResolver {
public final Cursor query(final Uri uri, String[] projection,
String selection, String[] selectionArgs, String sortOrder,
CancellationSignal cancellationSignal) {
- IContentProvider provider = acquireProvider(uri);
- if (provider == null) {
+ IContentProvider unstableProvider = acquireUnstableProvider(uri);
+ if (unstableProvider == null) {
return null;
}
+ IContentProvider stableProvider = null;
try {
long startTime = SystemClock.uptimeMillis();
ICancellationSignal remoteCancellationSignal = null;
if (cancellationSignal != null) {
cancellationSignal.throwIfCanceled();
- remoteCancellationSignal = provider.createCancellationSignal();
+ remoteCancellationSignal = unstableProvider.createCancellationSignal();
cancellationSignal.setRemote(remoteCancellationSignal);
}
- Cursor qCursor = provider.query(uri, projection,
- selection, selectionArgs, sortOrder, remoteCancellationSignal);
+ Cursor qCursor;
+ try {
+ qCursor = unstableProvider.query(uri, projection,
+ selection, selectionArgs, sortOrder, remoteCancellationSignal);
+ } catch (DeadObjectException e) {
+ // The remote process has died... but we only hold an unstable
+ // reference though, so we might recover!!! Let's try!!!!
+ // This is exciting!!1!!1!!!!1
+ unstableProviderDied(unstableProvider);
+ stableProvider = acquireProvider(uri);
+ if (stableProvider == null) {
+ return null;
+ }
+ qCursor = stableProvider.query(uri, projection,
+ selection, selectionArgs, sortOrder, remoteCancellationSignal);
+ }
if (qCursor == null) {
- releaseProvider(provider);
return null;
}
// force query execution
@@ -375,16 +389,21 @@ public abstract class ContentResolver {
long durationMillis = SystemClock.uptimeMillis() - startTime;
maybeLogQueryToEventLog(durationMillis, uri, projection, selection, sortOrder);
// Wrap the cursor object into CursorWrapperInner object
- return new CursorWrapperInner(qCursor, provider);
+ CursorWrapperInner wrapper = new CursorWrapperInner(qCursor,
+ stableProvider != null ? stableProvider : acquireProvider(uri));
+ stableProvider = null;
+ return wrapper;
} catch (RemoteException e) {
- releaseProvider(provider);
-
// Arbitrary and not worth documenting, as Activity
// Manager will kill this process shortly anyway.
return null;
- } catch (RuntimeException e) {
- releaseProvider(provider);
- throw e;
+ } finally {
+ if (unstableProvider != null) {
+ releaseUnstableProvider(unstableProvider);
+ }
+ if (stableProvider != null) {
+ releaseProvider(stableProvider);
+ }
}
}
@@ -592,49 +611,63 @@ public abstract class ContentResolver {
if ("r".equals(mode)) {
return openTypedAssetFileDescriptor(uri, "*/*", null);
} else {
- int n = 0;
- while (true) {
- n++;
- IContentProvider provider = acquireUnstableProvider(uri);
- if (provider == null) {
- throw new FileNotFoundException("No content provider: " + uri);
- }
+ IContentProvider unstableProvider = acquireUnstableProvider(uri);
+ if (unstableProvider == null) {
+ throw new FileNotFoundException("No content provider: " + uri);
+ }
+ IContentProvider stableProvider = null;
+ AssetFileDescriptor fd = null;
+
+ try {
try {
- AssetFileDescriptor fd = provider.openAssetFile(uri, mode);
+ fd = unstableProvider.openAssetFile(uri, mode);
if (fd == null) {
// The provider will be released by the finally{} clause
return null;
}
- ParcelFileDescriptor pfd = new ParcelFileDescriptorInner(
- fd.getParcelFileDescriptor(), provider);
-
- // Success! Don't release the provider when exiting, let
- // ParcelFileDescriptorInner do that when it is closed.
- provider = null;
-
- return new AssetFileDescriptor(pfd, fd.getStartOffset(),
- fd.getDeclaredLength());
- } catch (RemoteException e) {
- // The provider died for some reason. Since we are
- // acquiring it unstable, its process could have gotten
- // killed and need to be restarted. We'll retry a couple
- // times and if still can't succeed then fail.
- if (n <= 2) {
- try {
- Thread.sleep(100);
- } catch (InterruptedException e1) {
- }
- continue;
+ } catch (DeadObjectException e) {
+ // The remote process has died... but we only hold an unstable
+ // reference though, so we might recover!!! Let's try!!!!
+ // This is exciting!!1!!1!!!!1
+ unstableProviderDied(unstableProvider);
+ stableProvider = acquireProvider(uri);
+ if (stableProvider == null) {
+ throw new FileNotFoundException("No content provider: " + uri);
}
- // Whatever, whatever, we'll go away.
- throw new FileNotFoundException("Dead content provider: " + uri);
- } catch (FileNotFoundException e) {
- throw e;
- } finally {
- if (provider != null) {
- releaseUnstableProvider(provider);
+ fd = stableProvider.openAssetFile(uri, mode);
+ if (fd == null) {
+ // The provider will be released by the finally{} clause
+ return null;
}
}
+
+ if (stableProvider == null) {
+ stableProvider = acquireProvider(uri);
+ }
+ releaseUnstableProvider(unstableProvider);
+ ParcelFileDescriptor pfd = new ParcelFileDescriptorInner(
+ fd.getParcelFileDescriptor(), stableProvider);
+
+ // Success! Don't release the provider when exiting, let
+ // ParcelFileDescriptorInner do that when it is closed.
+ stableProvider = null;
+
+ return new AssetFileDescriptor(pfd, fd.getStartOffset(),
+ fd.getDeclaredLength());
+
+ } catch (RemoteException e) {
+ // Whatever, whatever, we'll go away.
+ throw new FileNotFoundException(
+ "Failed opening content provider: " + uri);
+ } catch (FileNotFoundException e) {
+ throw e;
+ } finally {
+ if (stableProvider != null) {
+ releaseProvider(stableProvider);
+ }
+ if (unstableProvider != null) {
+ releaseUnstableProvider(unstableProvider);
+ }
}
}
}
@@ -670,49 +703,63 @@ public abstract class ContentResolver {
*/
public final AssetFileDescriptor openTypedAssetFileDescriptor(Uri uri,
String mimeType, Bundle opts) throws FileNotFoundException {
- int n = 0;
- while (true) {
- n++;
- IContentProvider provider = acquireUnstableProvider(uri);
- if (provider == null) {
- throw new FileNotFoundException("No content provider: " + uri);
- }
+ IContentProvider unstableProvider = acquireUnstableProvider(uri);
+ if (unstableProvider == null) {
+ throw new FileNotFoundException("No content provider: " + uri);
+ }
+ IContentProvider stableProvider = null;
+ AssetFileDescriptor fd = null;
+
+ try {
try {
- AssetFileDescriptor fd = provider.openTypedAssetFile(uri, mimeType, opts);
+ fd = unstableProvider.openTypedAssetFile(uri, mimeType, opts);
if (fd == null) {
// The provider will be released by the finally{} clause
return null;
}
- ParcelFileDescriptor pfd = new ParcelFileDescriptorInner(
- fd.getParcelFileDescriptor(), provider);
-
- // Success! Don't release the provider when exiting, let
- // ParcelFileDescriptorInner do that when it is closed.
- provider = null;
-
- return new AssetFileDescriptor(pfd, fd.getStartOffset(),
- fd.getDeclaredLength());
- } catch (RemoteException e) {
- // The provider died for some reason. Since we are
- // acquiring it unstable, its process could have gotten
- // killed and need to be restarted. We'll retry a couple
- // times and if still can't succeed then fail.
- if (n <= 2) {
- try {
- Thread.sleep(100);
- } catch (InterruptedException e1) {
- }
- continue;
+ } catch (DeadObjectException e) {
+ // The remote process has died... but we only hold an unstable
+ // reference though, so we might recover!!! Let's try!!!!
+ // This is exciting!!1!!1!!!!1
+ unstableProviderDied(unstableProvider);
+ stableProvider = acquireProvider(uri);
+ if (stableProvider == null) {
+ throw new FileNotFoundException("No content provider: " + uri);
}
- // Whatever, whatever, we'll go away.
- throw new FileNotFoundException("Dead content provider: " + uri);
- } catch (FileNotFoundException e) {
- throw e;
- } finally {
- if (provider != null) {
- releaseUnstableProvider(provider);
+ fd = stableProvider.openTypedAssetFile(uri, mimeType, opts);
+ if (fd == null) {
+ // The provider will be released by the finally{} clause
+ return null;
}
}
+
+ if (stableProvider == null) {
+ stableProvider = acquireProvider(uri);
+ }
+ releaseUnstableProvider(unstableProvider);
+ ParcelFileDescriptor pfd = new ParcelFileDescriptorInner(
+ fd.getParcelFileDescriptor(), stableProvider);
+
+ // Success! Don't release the provider when exiting, let
+ // ParcelFileDescriptorInner do that when it is closed.
+ stableProvider = null;
+
+ return new AssetFileDescriptor(pfd, fd.getStartOffset(),
+ fd.getDeclaredLength());
+
+ } catch (RemoteException e) {
+ // Whatever, whatever, we'll go away.
+ throw new FileNotFoundException(
+ "Failed opening content provider: " + uri);
+ } catch (FileNotFoundException e) {
+ throw e;
+ } finally {
+ if (stableProvider != null) {
+ releaseProvider(stableProvider);
+ }
+ if (unstableProvider != null) {
+ releaseUnstableProvider(unstableProvider);
+ }
}
}
@@ -1061,7 +1108,7 @@ public abstract class ContentResolver {
if (name == null) {
return null;
}
- return acquireProvider(mContext, name);
+ return acquireUnstableProvider(mContext, name);
}
/**
@@ -1113,10 +1160,15 @@ public abstract class ContentResolver {
* use it as needed and it won't disappear, even if your process is in the
* background. If using this method, you need to take care to deal with any
* failures when communicating with the provider, and be sure to close it
- * so that it can be re-opened later.
+ * so that it can be re-opened later. In particular, catching a
+ * {@link android.os.DeadObjectException} from the calls there will let you
+ * know that the content provider has gone away; at that point the current
+ * ContentProviderClient object is invalid, and you should release it. You
+ * can acquire a new one if you would like to try to restart the provider
+ * and perform new operations on it.
*/
public final ContentProviderClient acquireUnstableContentProviderClient(Uri uri) {
- IContentProvider provider = acquireProvider(uri);
+ IContentProvider provider = acquireUnstableProvider(uri);
if (provider != null) {
return new ContentProviderClient(this, provider, false);
}
@@ -1133,10 +1185,15 @@ public abstract class ContentResolver {
* use it as needed and it won't disappear, even if your process is in the
* background. If using this method, you need to take care to deal with any
* failures when communicating with the provider, and be sure to close it
- * so that it can be re-opened later.
+ * so that it can be re-opened later. In particular, catching a
+ * {@link android.os.DeadObjectException} from the calls there will let you
+ * know that the content provider has gone away; at that point the current
+ * ContentProviderClient object is invalid, and you should release it. You
+ * can acquire a new one if you would like to try to restart the provider
+ * and perform new operations on it.
*/
public final ContentProviderClient acquireUnstableContentProviderClient(String name) {
- IContentProvider provider = acquireProvider(name);
+ IContentProvider provider = acquireUnstableProvider(name);
if (provider != null) {
return new ContentProviderClient(this, provider, false);
}
@@ -1780,7 +1837,6 @@ public abstract class ContentResolver {
private final class ParcelFileDescriptorInner extends ParcelFileDescriptor {
private final IContentProvider mContentProvider;
- public static final String TAG="ParcelFileDescriptorInner";
private boolean mReleaseProviderFlag = false;
ParcelFileDescriptorInner(ParcelFileDescriptor pfd, IContentProvider icp) {
@@ -1792,7 +1848,7 @@ public abstract class ContentResolver {
public void close() throws IOException {
if(!mReleaseProviderFlag) {
super.close();
- ContentResolver.this.releaseUnstableProvider(mContentProvider);
+ ContentResolver.this.releaseProvider(mContentProvider);
mReleaseProviderFlag = true;
}
}
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index ad52e13..e180df4 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -935,7 +935,17 @@ public class PackageParser {
com.android.internal.R.styleable.AndroidManifest_installLocation,
PARSE_DEFAULT_INSTALL_LOCATION);
pkg.applicationInfo.installLocation = pkg.installLocation;
-
+
+ /* Set the global "forward lock" flag */
+ if ((flags & PARSE_FORWARD_LOCK) != 0) {
+ pkg.applicationInfo.flags |= ApplicationInfo.FLAG_FORWARD_LOCK;
+ }
+
+ /* Set the global "on SD card" flag */
+ if ((flags & PARSE_ON_SDCARD) != 0) {
+ pkg.applicationInfo.flags |= ApplicationInfo.FLAG_EXTERNAL_STORAGE;
+ }
+
// Resource boolean are -1, so 1 means we don't know the value.
int supportsSmallScreens = 1;
int supportsNormalScreens = 1;
@@ -1726,14 +1736,6 @@ public class PackageParser {
}
}
- if ((flags & PARSE_FORWARD_LOCK) != 0) {
- ai.flags |= ApplicationInfo.FLAG_FORWARD_LOCK;
- }
-
- if ((flags & PARSE_ON_SDCARD) != 0) {
- ai.flags |= ApplicationInfo.FLAG_EXTERNAL_STORAGE;
- }
-
if (sa.getBoolean(
com.android.internal.R.styleable.AndroidManifestApplication_debuggable,
false)) {
diff --git a/core/java/android/hardware/Camera.java b/core/java/android/hardware/Camera.java
index 89068e7..4d9077f 100644
--- a/core/java/android/hardware/Camera.java
+++ b/core/java/android/hardware/Camera.java
@@ -736,8 +736,8 @@ public class Camera {
return;
case CAMERA_MSG_PREVIEW_FRAME:
- if (mPreviewCallback != null) {
- PreviewCallback cb = mPreviewCallback;
+ PreviewCallback pCb = mPreviewCallback;
+ if (pCb != null) {
if (mOneShot) {
// Clear the callback variable before the callback
// in case the app calls setPreviewCallback from
@@ -749,7 +749,7 @@ public class Camera {
// Set to oneshot mode again.
setHasPreviewCallback(true, false);
}
- cb.onPreviewFrame((byte[])msg.obj, mCamera);
+ pCb.onPreviewFrame((byte[])msg.obj, mCamera);
}
return;
@@ -1059,6 +1059,7 @@ public class Camera {
}
native_takePicture(msgType);
+ mFaceDetectionRunning = false;
}
/**
diff --git a/core/java/android/inputmethodservice/InputMethodService.java b/core/java/android/inputmethodservice/InputMethodService.java
index 33dea6c..46153e7 100644
--- a/core/java/android/inputmethodservice/InputMethodService.java
+++ b/core/java/android/inputmethodservice/InputMethodService.java
@@ -1892,6 +1892,13 @@ public class InputMethodService extends AbstractInputMethodService {
* {@link KeyEvent#FLAG_KEEP_TOUCH_MODE KeyEvent.FLAG_KEEP_TOUCH_MODE}, so
* that they don't impact the current touch mode of the UI.
*
+ * <p>Note that it's discouraged to send such key events in normal operation;
+ * this is mainly for use with {@link android.text.InputType#TYPE_NULL} type
+ * text fields, or for non-rich input methods. A reasonably capable software
+ * input method should use the
+ * {@link android.view.inputmethod.InputConnection#commitText} family of methods
+ * to send text to an application, rather than sending key events.</p>
+ *
* @param keyEventCode The raw key code to send, as defined by
* {@link KeyEvent}.
*/
@@ -1949,7 +1956,11 @@ public class InputMethodService extends AbstractInputMethodService {
* {@link InputConnection#commitText InputConnection.commitText()} with
* the character; some, however, may be handled different. In particular,
* the enter character ('\n') will either be delivered as an action code
- * or a raw key event, as appropriate.
+ * or a raw key event, as appropriate. Consider this as a convenience
+ * method for IMEs that do not have a full implementation of actions; a
+ * fully complying IME will decide of the right action for each event and
+ * will likely never call this method except maybe to handle events coming
+ * from an actual hardware keyboard.
*
* @param charCode The UTF-16 character code to send.
*/
diff --git a/core/java/android/provider/ContactsContract.java b/core/java/android/provider/ContactsContract.java
index 2782dca..e8f87bb 100644
--- a/core/java/android/provider/ContactsContract.java
+++ b/core/java/android/provider/ContactsContract.java
@@ -24,6 +24,7 @@ import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Context;
+import android.content.ContextWrapper;
import android.content.CursorEntityIterator;
import android.content.Entity;
import android.content.EntityIterator;
@@ -7711,9 +7712,19 @@ public final class ContactsContract {
*/
public static void showQuickContact(Context context, Rect target, Uri lookupUri, int mode,
String[] excludeMimes) {
+ // When launching from an Activiy, we don't want to start a new task, but otherwise
+ // we *must* start a new task. (Otherwise startActivity() would crash.)
+ Context actualContext = context;
+ while ((actualContext instanceof ContextWrapper)
+ && !(actualContext instanceof Activity)) {
+ actualContext = ((ContextWrapper) actualContext).getBaseContext();
+ }
+ final int intentFlags = (actualContext instanceof Activity)
+ ? Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET
+ : Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK;
+
// Launch pivot dialog through intent for now
- final Intent intent = new Intent(ACTION_QUICK_CONTACT)
- .addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
+ final Intent intent = new Intent(ACTION_QUICK_CONTACT).addFlags(intentFlags);
intent.setData(lookupUri);
intent.setSourceBounds(target);
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 8b7ee0e..8630204 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -2886,6 +2886,15 @@ public final class Settings {
"enabled_accessibility_services";
/**
+ * List of the accessibility services to which the user has graned
+ * permission to put the device into touch exploration mode.
+ *
+ * @hide
+ */
+ public static final String TOUCH_EXPLORATION_GRANTED_ACCESSIBILITY_SERVICES =
+ "touch_exploration_granted_accessibility_services";
+
+ /**
* Whether to speak passwords while in accessibility mode.
*/
public static final String ACCESSIBILITY_SPEAK_PASSWORD = "speak_password";
@@ -4292,6 +4301,7 @@ public final class Settings {
ACCESSIBILITY_SCRIPT_INJECTION,
BACKUP_AUTO_RESTORE,
ENABLED_ACCESSIBILITY_SERVICES,
+ TOUCH_EXPLORATION_GRANTED_ACCESSIBILITY_SERVICES,
TOUCH_EXPLORATION_ENABLED,
ACCESSIBILITY_ENABLED,
ACCESSIBILITY_SPEAK_PASSWORD,
diff --git a/core/java/android/server/BluetoothA2dpService.java b/core/java/android/server/BluetoothA2dpService.java
index 300bc68..08a99d2 100644
--- a/core/java/android/server/BluetoothA2dpService.java
+++ b/core/java/android/server/BluetoothA2dpService.java
@@ -33,7 +33,11 @@ import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.media.AudioManager;
+import android.os.Handler;
+import android.os.Message;
import android.os.ParcelUuid;
+import android.os.PowerManager;
+import android.os.PowerManager.WakeLock;
import android.provider.Settings;
import android.util.Log;
@@ -65,6 +69,10 @@ public class BluetoothA2dpService extends IBluetoothA2dp.Stub {
private final BluetoothAdapter mAdapter;
private int mTargetA2dpState;
private BluetoothDevice mPlayingA2dpDevice;
+ private IntentBroadcastHandler mIntentBroadcastHandler;
+ private final WakeLock mWakeLock;
+
+ private static final int MSG_CONNECTION_STATE_CHANGED = 0;
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
@Override
@@ -131,6 +139,11 @@ public class BluetoothA2dpService extends IBluetoothA2dp.Stub {
public BluetoothA2dpService(Context context, BluetoothService bluetoothService) {
mContext = context;
+ PowerManager pm = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
+ mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "BluetoothA2dpService");
+
+ mIntentBroadcastHandler = new IntentBroadcastHandler();
+
mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
mBluetoothService = bluetoothService;
@@ -514,17 +527,15 @@ public class BluetoothA2dpService extends IBluetoothA2dp.Stub {
adjustOtherSinkPriorities(device);
}
- Intent intent = new Intent(BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED);
- intent.putExtra(BluetoothDevice.EXTRA_DEVICE, device);
- intent.putExtra(BluetoothProfile.EXTRA_PREVIOUS_STATE, prevState);
- intent.putExtra(BluetoothProfile.EXTRA_STATE, state);
- intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
- mContext.sendBroadcast(intent, BLUETOOTH_PERM);
+ int delay = mAudioManager.setBluetoothA2dpDeviceConnectionState(device, state);
- if (DBG) log("A2DP state : device: " + device + " State:" + prevState + "->" + state);
-
- mBluetoothService.sendConnectionStateChange(device, BluetoothProfile.A2DP, state,
- prevState);
+ mWakeLock.acquire();
+ mIntentBroadcastHandler.sendMessageDelayed(mIntentBroadcastHandler.obtainMessage(
+ MSG_CONNECTION_STATE_CHANGED,
+ prevState,
+ state,
+ device),
+ delay);
}
}
@@ -586,6 +597,34 @@ public class BluetoothA2dpService extends IBluetoothA2dp.Stub {
}
}
+ /** Handles A2DP connection state change intent broadcasts. */
+ private class IntentBroadcastHandler extends Handler {
+
+ private void onConnectionStateChanged(BluetoothDevice device, int prevState, int state) {
+ Intent intent = new Intent(BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED);
+ intent.putExtra(BluetoothDevice.EXTRA_DEVICE, device);
+ intent.putExtra(BluetoothProfile.EXTRA_PREVIOUS_STATE, prevState);
+ intent.putExtra(BluetoothProfile.EXTRA_STATE, state);
+ intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
+ mContext.sendBroadcast(intent, BLUETOOTH_PERM);
+
+ if (DBG) log("A2DP state : device: " + device + " State:" + prevState + "->" + state);
+
+ mBluetoothService.sendConnectionStateChange(device, BluetoothProfile.A2DP, state,
+ prevState);
+ }
+
+ @Override
+ public void handleMessage(Message msg) {
+ switch (msg.what) {
+ case MSG_CONNECTION_STATE_CHANGED:
+ onConnectionStateChanged((BluetoothDevice) msg.obj, msg.arg1, msg.arg2);
+ mWakeLock.release();
+ break;
+ }
+ }
+ }
+
@Override
protected synchronized void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DUMP, TAG);
diff --git a/core/java/android/text/method/BaseKeyListener.java b/core/java/android/text/method/BaseKeyListener.java
index 7e29dc7..4fede32 100644
--- a/core/java/android/text/method/BaseKeyListener.java
+++ b/core/java/android/text/method/BaseKeyListener.java
@@ -28,6 +28,10 @@ import android.widget.TextView;
* Provides a basic foundation for entering and editing text.
* Subclasses should override {@link #onKeyDown} and {@link #onKeyUp} to insert
* characters as keys are pressed.
+ * <p></p>
+ * As for all implementations of {@link KeyListener}, this class is only concerned
+ * with hardware keyboards. Software input methods have no obligation to trigger
+ * the methods in this class.
*/
public abstract class BaseKeyListener extends MetaKeyKeyListener
implements KeyListener {
diff --git a/core/java/android/text/method/DateKeyListener.java b/core/java/android/text/method/DateKeyListener.java
index 7c11434..e6f63d1 100644
--- a/core/java/android/text/method/DateKeyListener.java
+++ b/core/java/android/text/method/DateKeyListener.java
@@ -21,6 +21,10 @@ import android.text.InputType;
/**
* For entering dates in a text field.
+ * <p></p>
+ * As for all implementations of {@link KeyListener}, this class is only concerned
+ * with hardware keyboards. Software input methods have no obligation to trigger
+ * the methods in this class.
*/
public class DateKeyListener extends NumberKeyListener
{
diff --git a/core/java/android/text/method/DateTimeKeyListener.java b/core/java/android/text/method/DateTimeKeyListener.java
index f8ebc40..523e986 100644
--- a/core/java/android/text/method/DateTimeKeyListener.java
+++ b/core/java/android/text/method/DateTimeKeyListener.java
@@ -21,6 +21,10 @@ import android.view.KeyEvent;
/**
* For entering dates and times in the same text field.
+ * <p></p>
+ * As for all implementations of {@link KeyListener}, this class is only concerned
+ * with hardware keyboards. Software input methods have no obligation to trigger
+ * the methods in this class.
*/
public class DateTimeKeyListener extends NumberKeyListener
{
diff --git a/core/java/android/text/method/DialerKeyListener.java b/core/java/android/text/method/DialerKeyListener.java
index 07127b7..ce51fae 100644
--- a/core/java/android/text/method/DialerKeyListener.java
+++ b/core/java/android/text/method/DialerKeyListener.java
@@ -23,6 +23,10 @@ import android.text.Spannable;
/**
* For dialing-only text entry
+ * <p></p>
+ * As for all implementations of {@link KeyListener}, this class is only concerned
+ * with hardware keyboards. Software input methods have no obligation to trigger
+ * the methods in this class.
*/
public class DialerKeyListener extends NumberKeyListener
{
diff --git a/core/java/android/text/method/DigitsKeyListener.java b/core/java/android/text/method/DigitsKeyListener.java
index f0f072c..3d9daed 100644
--- a/core/java/android/text/method/DigitsKeyListener.java
+++ b/core/java/android/text/method/DigitsKeyListener.java
@@ -24,6 +24,10 @@ import android.view.KeyEvent;
/**
* For digits-only text entry
+ * <p></p>
+ * As for all implementations of {@link KeyListener}, this class is only concerned
+ * with hardware keyboards. Software input methods have no obligation to trigger
+ * the methods in this class.
*/
public class DigitsKeyListener extends NumberKeyListener
{
diff --git a/core/java/android/text/method/KeyListener.java b/core/java/android/text/method/KeyListener.java
index 318149a..bb79ecd 100644
--- a/core/java/android/text/method/KeyListener.java
+++ b/core/java/android/text/method/KeyListener.java
@@ -27,6 +27,12 @@ import android.view.View;
* {@link android.view.inputmethod.InputMethod}; it should only be used
* for cases where an application has its own on-screen keypad and also wants
* to process hard keyboard events to match it.
+ * <p></p>
+ * Key presses on soft input methods are not required to trigger the methods
+ * in this listener, and are in fact discouraged to do so. The default
+ * android keyboard will not trigger these for any key to any application
+ * targetting Jelly Bean or later, and will only deliver it for some
+ * key presses to applications targetting Ice Cream Sandwich or earlier.
*/
public interface KeyListener {
/**
diff --git a/core/java/android/text/method/MultiTapKeyListener.java b/core/java/android/text/method/MultiTapKeyListener.java
index 2a739fa..95ac0a1 100644
--- a/core/java/android/text/method/MultiTapKeyListener.java
+++ b/core/java/android/text/method/MultiTapKeyListener.java
@@ -28,6 +28,10 @@ import android.util.SparseArray;
* This is the standard key listener for alphabetic input on 12-key
* keyboards. You should generally not need to instantiate this yourself;
* TextKeyListener will do it for you.
+ * <p></p>
+ * As for all implementations of {@link KeyListener}, this class is only concerned
+ * with hardware keyboards. Software input methods have no obligation to trigger
+ * the methods in this class.
*/
public class MultiTapKeyListener extends BaseKeyListener
implements SpanWatcher {
diff --git a/core/java/android/text/method/NumberKeyListener.java b/core/java/android/text/method/NumberKeyListener.java
index 1e72309..5d4c732 100644
--- a/core/java/android/text/method/NumberKeyListener.java
+++ b/core/java/android/text/method/NumberKeyListener.java
@@ -27,6 +27,10 @@ import android.text.Spanned;
/**
* For numeric text entry
+ * <p></p>
+ * As for all implementations of {@link KeyListener}, this class is only concerned
+ * with hardware keyboards. Software input methods have no obligation to trigger
+ * the methods in this class.
*/
public abstract class NumberKeyListener extends BaseKeyListener
implements InputFilter
diff --git a/core/java/android/text/method/QwertyKeyListener.java b/core/java/android/text/method/QwertyKeyListener.java
index 4c82b81..c5261f3 100644
--- a/core/java/android/text/method/QwertyKeyListener.java
+++ b/core/java/android/text/method/QwertyKeyListener.java
@@ -27,6 +27,10 @@ import android.view.View;
* This is the standard key listener for alphabetic input on qwerty
* keyboards. You should generally not need to instantiate this yourself;
* TextKeyListener will do it for you.
+ * <p></p>
+ * As for all implementations of {@link KeyListener}, this class is only concerned
+ * with hardware keyboards. Software input methods have no obligation to trigger
+ * the methods in this class.
*/
public class QwertyKeyListener extends BaseKeyListener {
private static QwertyKeyListener[] sInstance =
diff --git a/core/java/android/text/method/TextKeyListener.java b/core/java/android/text/method/TextKeyListener.java
index 8312fe1..994f3d7 100644
--- a/core/java/android/text/method/TextKeyListener.java
+++ b/core/java/android/text/method/TextKeyListener.java
@@ -33,6 +33,10 @@ import java.lang.ref.WeakReference;
/**
* This is the key listener for typing normal text. It delegates to
* other key listeners appropriate to the current keyboard and language.
+ * <p></p>
+ * As for all implementations of {@link KeyListener}, this class is only concerned
+ * with hardware keyboards. Software input methods have no obligation to trigger
+ * the methods in this class.
*/
public class TextKeyListener extends BaseKeyListener implements SpanWatcher {
private static TextKeyListener[] sInstance =
diff --git a/core/java/android/text/method/TimeKeyListener.java b/core/java/android/text/method/TimeKeyListener.java
index 3fbfd8c..c5bfd5c 100644
--- a/core/java/android/text/method/TimeKeyListener.java
+++ b/core/java/android/text/method/TimeKeyListener.java
@@ -21,6 +21,10 @@ import android.text.InputType;
/**
* For entering times in a text field.
+ * <p></p>
+ * As for all implementations of {@link KeyListener}, this class is only concerned
+ * with hardware keyboards. Software input methods have no obligation to trigger
+ * the methods in this class.
*/
public class TimeKeyListener extends NumberKeyListener
{
diff --git a/core/java/android/view/AccessibilityIterators.java b/core/java/android/view/AccessibilityIterators.java
index cd54f24..2a7dc18 100644
--- a/core/java/android/view/AccessibilityIterators.java
+++ b/core/java/android/view/AccessibilityIterators.java
@@ -47,7 +47,6 @@ public final class AccessibilityIterators {
* @hide
*/
public static abstract class AbstractTextSegmentIterator implements TextSegmentIterator {
- protected static final int DONE = -1;
protected String mText;
@@ -104,20 +103,20 @@ public final class AccessibilityIterators {
if (offset >= textLegth) {
return null;
}
- int start = -1;
- if (offset < 0) {
- offset = 0;
- if (mImpl.isBoundary(offset)) {
- start = offset;
- }
- }
+ int start = offset;
if (start < 0) {
- start = mImpl.following(offset);
+ start = 0;
}
- if (start < 0) {
- return null;
+ while (!mImpl.isBoundary(start)) {
+ start = mImpl.following(start);
+ if (start == BreakIterator.DONE) {
+ return null;
+ }
}
final int end = mImpl.following(start);
+ if (end == BreakIterator.DONE) {
+ return null;
+ }
return getRange(start, end);
}
@@ -130,20 +129,20 @@ public final class AccessibilityIterators {
if (offset <= 0) {
return null;
}
- int end = -1;
- if (offset > mText.length()) {
- offset = mText.length();
- if (mImpl.isBoundary(offset)) {
- end = offset;
- }
+ int end = offset;
+ if (end > textLegth) {
+ end = textLegth;
}
- if (end < 0) {
- end = mImpl.preceding(offset);
+ while (!mImpl.isBoundary(end)) {
+ end = mImpl.preceding(end);
+ if (end == BreakIterator.DONE) {
+ return null;
+ }
}
- if (end < 0) {
+ final int start = mImpl.preceding(end);
+ if (start == BreakIterator.DONE) {
return null;
}
- final int start = mImpl.preceding(end);
return getRange(start, end);
}
@@ -195,25 +194,20 @@ public final class AccessibilityIterators {
if (offset >= mText.length()) {
return null;
}
- int start = -1;
- if (offset < 0) {
- offset = 0;
- if (mImpl.isBoundary(offset) && isLetterOrDigit(offset)) {
- start = offset;
- }
- }
+ int start = offset;
if (start < 0) {
- while ((offset = mImpl.following(offset)) != DONE) {
- if (isLetterOrDigit(offset)) {
- start = offset;
- break;
- }
+ start = 0;
+ }
+ while (!isLetterOrDigit(start) && !isStartBoundary(start)) {
+ start = mImpl.following(start);
+ if (start == BreakIterator.DONE) {
+ return null;
}
}
- if (start < 0) {
+ final int end = mImpl.following(start);
+ if (end == BreakIterator.DONE || !isEndBoundary(end)) {
return null;
}
- final int end = mImpl.following(start);
return getRange(start, end);
}
@@ -226,28 +220,33 @@ public final class AccessibilityIterators {
if (offset <= 0) {
return null;
}
- int end = -1;
- if (offset > mText.length()) {
- offset = mText.length();
- if (mImpl.isBoundary(offset) && offset > 0 && isLetterOrDigit(offset - 1)) {
- end = offset;
- }
+ int end = offset;
+ if (end > textLegth) {
+ end = textLegth;
}
- if (end < 0) {
- while ((offset = mImpl.preceding(offset)) != DONE) {
- if (offset > 0 && isLetterOrDigit(offset - 1)) {
- end = offset;
- break;
- }
+ while (end > 0 && !isLetterOrDigit(end - 1) && !isEndBoundary(end)) {
+ end = mImpl.preceding(end);
+ if (end == BreakIterator.DONE) {
+ return null;
}
}
- if (end < 0) {
+ final int start = mImpl.preceding(end);
+ if (start == BreakIterator.DONE || !isStartBoundary(start)) {
return null;
}
- final int start = mImpl.preceding(end);
return getRange(start, end);
}
+ private boolean isStartBoundary(int index) {
+ return isLetterOrDigit(index)
+ && (index == 0 || !isLetterOrDigit(index - 1));
+ }
+
+ private boolean isEndBoundary(int index) {
+ return (index > 0 && isLetterOrDigit(index - 1))
+ && (index == mText.length() || !isLetterOrDigit(index));
+ }
+
private boolean isLetterOrDigit(int index) {
if (index >= 0 && index < mText.length()) {
final int codePoint = mText.codePointAt(index);
@@ -276,31 +275,19 @@ public final class AccessibilityIterators {
if (offset >= textLength) {
return null;
}
- int start = -1;
- if (offset < 0) {
- start = 0;
- } else {
- for (int i = offset + 1; i < textLength; i++) {
- if (mText.charAt(i) == '\n') {
- start = i;
- break;
- }
- }
- }
+ int start = offset;
if (start < 0) {
- return null;
+ start = 0;
}
- while (start < textLength && mText.charAt(start) == '\n') {
+ while (start < textLength && mText.charAt(start) == '\n'
+ && !isStartBoundary(start)) {
start++;
}
- int end = start;
- for (int i = end + 1; i < textLength; i++) {
- end = i;
- if (mText.charAt(i) == '\n') {
- break;
- }
+ if (start >= textLength) {
+ return null;
}
- while (end < textLength && mText.charAt(end) == '\n') {
+ int end = start + 1;
+ while (end < textLength && !isEndBoundary(end)) {
end++;
}
return getRange(start, end);
@@ -315,38 +302,31 @@ public final class AccessibilityIterators {
if (offset <= 0) {
return null;
}
- int end = -1;
- if (offset > mText.length()) {
- end = mText.length();
- } else {
- if (offset > 0 && mText.charAt(offset - 1) == '\n') {
- offset--;
- }
- for (int i = offset - 1; i >= 0; i--) {
- if (i > 0 && mText.charAt(i - 1) == '\n') {
- end = i;
- break;
- }
- }
+ int end = offset;
+ if (end > textLength) {
+ end = textLength;
+ }
+ while(end > 0 && mText.charAt(end - 1) == '\n' && !isEndBoundary(end)) {
+ end--;
}
if (end <= 0) {
return null;
}
- int start = end;
- while (start > 0 && mText.charAt(start - 1) == '\n') {
+ int start = end - 1;
+ while (start > 0 && !isStartBoundary(start)) {
start--;
}
- if (start == 0 && mText.charAt(start) == '\n') {
- return null;
- }
- for (int i = start - 1; i >= 0; i--) {
- start = i;
- if (start > 0 && mText.charAt(i - 1) == '\n') {
- break;
- }
- }
- start = Math.max(0, start);
return getRange(start, end);
}
+
+ private boolean isStartBoundary(int index) {
+ return (mText.charAt(index) != '\n'
+ && (index == 0 || mText.charAt(index - 1) == '\n'));
+ }
+
+ private boolean isEndBoundary(int index) {
+ return (index > 0 && mText.charAt(index - 1) != '\n'
+ && (index == mText.length() || mText.charAt(index) == '\n'));
+ }
}
}
diff --git a/core/java/android/view/InputDevice.java b/core/java/android/view/InputDevice.java
index 2ea0360..3bb9c01 100755
--- a/core/java/android/view/InputDevice.java
+++ b/core/java/android/view/InputDevice.java
@@ -459,6 +459,18 @@ public final class InputDevice implements Parcelable {
}
/**
+ * Returns true if the device is a full keyboard.
+ *
+ * @return True if the device is a full keyboard.
+ *
+ * @hide
+ */
+ public boolean isFullKeyboard() {
+ return (mSources & SOURCE_KEYBOARD) == SOURCE_KEYBOARD
+ && mKeyboardType == KEYBOARD_TYPE_ALPHABETIC;
+ }
+
+ /**
* Gets the name of this input device.
* @return The input device name.
*/
diff --git a/core/java/android/view/KeyEvent.java b/core/java/android/view/KeyEvent.java
index ace7aa8..1080229 100755
--- a/core/java/android/view/KeyEvent.java
+++ b/core/java/android/view/KeyEvent.java
@@ -52,6 +52,19 @@ import android.view.KeyCharacterMap.KeyData;
* to characters. Be aware that there may be multiple key input devices active
* at the same time and each will have its own key character map.
* </p><p>
+ * As soft input methods can use multiple and inventive ways of inputting text,
+ * there is no guarantee that any key press on a soft keyboard will generate a key
+ * event: this is left to the IME's discretion, and in fact sending such events is
+ * discouraged. You should never rely on receiving KeyEvents for any key on a soft
+ * input method. In particular, the default software keyboard will never send any
+ * key event to any application targetting Jelly Bean or later, and will only send
+ * events for some presses of the delete and return keys to applications targetting
+ * Ice Cream Sandwich or earlier. Be aware that other software input methods may
+ * never send key events regardless of the version. Consider using editor actions
+ * like {@link android.view.inputmethod.EditorInfo#IME_ACTION_DONE} if you need
+ * specific interaction with the software keyboard, as it gives more visibility to
+ * the user as to how your application will react to key presses.
+ * </p><p>
* When interacting with an IME, the framework may deliver key events
* with the special action {@link #ACTION_MULTIPLE} that either specifies
* that single repeated key code or a sequence of characters to insert.
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 8cb5c85..9613149 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -204,12 +204,12 @@ import java.util.concurrent.CopyOnWriteArrayList;
* <tr>
* <td rowspan="4">Event processing</td>
* <td><code>{@link #onKeyDown(int, KeyEvent)}</code></td>
- * <td>Called when a new key event occurs.
+ * <td>Called when a new hardware key event occurs.
* </td>
* </tr>
* <tr>
* <td><code>{@link #onKeyUp(int, KeyEvent)}</code></td>
- * <td>Called when a key up event occurs.
+ * <td>Called when a hardware key up event occurs.
* </td>
* </tr>
* <tr>
@@ -1596,7 +1596,7 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
/**
* @hide
*/
- private int mAccessibilityCursorPosition = -1;
+ private int mAccessibilityCursorPosition = ACCESSIBILITY_CURSOR_POSITION_UNDEFINED;
/**
* The view's tag.
@@ -2086,7 +2086,8 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
// Accessiblity constants for mPrivateFlags2
/**
- * Shift for accessibility related bits in {@link #mPrivateFlags2}.
+ * Shift for the bits in {@link #mPrivateFlags2} related to the
+ * "importantForAccessibility" attribute.
*/
static final int IMPORTANT_FOR_ACCESSIBILITY_SHIFT = 20;
@@ -2142,6 +2143,72 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
*/
static final int VIEW_QUICK_REJECTED = 0x20000000;
+ // Accessiblity constants for mPrivateFlags2
+
+ /**
+ * Shift for the bits in {@link #mPrivateFlags2} related to the
+ * "accessibilityFocusable" attribute.
+ */
+ static final int ACCESSIBILITY_FOCUSABLE_SHIFT = 30;
+
+ /**
+ * The system determines whether the view can take accessibility focus - default (recommended).
+ * <p>
+ * Such a view is consideted by the focus search if it is:
+ * <ul>
+ * <li>
+ * Important for accessibility and actionable (clickable, long clickable, focusable)
+ * </li>
+ * <li>
+ * Important for accessibility, not actionable (clickable, long clickable, focusable),
+ * and does not have an actionable predecessor.
+ * </li>
+ * </ul>
+ * An accessibility srvice can request putting accessibility focus on such a view.
+ * </p>
+ *
+ * @hide
+ */
+ public static final int ACCESSIBILITY_FOCUSABLE_AUTO = 0x00000000;
+
+ /**
+ * The view can take accessibility focus.
+ * <p>
+ * A view that can take accessibility focus is always considered during focus
+ * search and an accessibility service can request putting accessibility focus
+ * on it.
+ * </p>
+ *
+ * @hide
+ */
+ public static final int ACCESSIBILITY_FOCUSABLE_YES = 0x00000001;
+
+ /**
+ * The view can not take accessibility focus.
+ * <p>
+ * A view that can not take accessibility focus is never considered during focus
+ * search and an accessibility service can not request putting accessibility focus
+ * on it.
+ * </p>
+ *
+ * @hide
+ */
+ public static final int ACCESSIBILITY_FOCUSABLE_NO = 0x00000002;
+
+ /**
+ * The default whether the view is accessiblity focusable.
+ */
+ static final int ACCESSIBILITY_FOCUSABLE_DEFAULT = ACCESSIBILITY_FOCUSABLE_AUTO;
+
+ /**
+ * Mask for obtainig the bits which specifies how to determine
+ * whether a view is accessibility focusable.
+ */
+ static final int ACCESSIBILITY_FOCUSABLE_MASK = (ACCESSIBILITY_FOCUSABLE_AUTO
+ | ACCESSIBILITY_FOCUSABLE_YES | ACCESSIBILITY_FOCUSABLE_NO)
+ << ACCESSIBILITY_FOCUSABLE_SHIFT;
+
+
/* End of masks for mPrivateFlags2 */
static final int DRAG_MASK = DRAG_CAN_ACCEPT | DRAG_HOVERED;
@@ -2468,6 +2535,11 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
public static final int FIND_VIEWS_WITH_ACCESSIBILITY_NODE_PROVIDERS = 0x00000004;
/**
+ * The undefined cursor position.
+ */
+ private static final int ACCESSIBILITY_CURSOR_POSITION_UNDEFINED = -1;
+
+ /**
* Indicates that the screen has changed state and is now off.
*
* @see #onScreenStateChanged(int)
@@ -3132,7 +3204,8 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
mPrivateFlags2 = (LAYOUT_DIRECTION_DEFAULT << LAYOUT_DIRECTION_MASK_SHIFT) |
(TEXT_DIRECTION_DEFAULT << TEXT_DIRECTION_MASK_SHIFT) |
(TEXT_ALIGNMENT_DEFAULT << TEXT_ALIGNMENT_MASK_SHIFT) |
- (IMPORTANT_FOR_ACCESSIBILITY_DEFAULT << IMPORTANT_FOR_ACCESSIBILITY_SHIFT);
+ (IMPORTANT_FOR_ACCESSIBILITY_DEFAULT << IMPORTANT_FOR_ACCESSIBILITY_SHIFT) |
+ (ACCESSIBILITY_FOCUSABLE_DEFAULT << ACCESSIBILITY_FOCUSABLE_SHIFT);
mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
setOverScrollMode(OVER_SCROLL_IF_CONTENT_SCROLLS);
mUserPaddingStart = -1;
@@ -4082,7 +4155,9 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
}
/**
- * Register a callback to be invoked when a key is pressed in this view.
+ * Register a callback to be invoked when a hardware key is pressed in this view.
+ * Key presses in software input methods will generally not trigger the methods of
+ * this listener.
* @param l the key listener to attach to this view
*/
public void setOnKeyListener(OnKeyListener l) {
@@ -4788,7 +4863,10 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
}
if (!isAccessibilityFocused()) {
- info.addAction(AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS);
+ final int mode = getAccessibilityFocusable();
+ if (mode == ACCESSIBILITY_FOCUSABLE_YES || mode == ACCESSIBILITY_FOCUSABLE_AUTO) {
+ info.addAction(AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS);
+ }
} else {
info.addAction(AccessibilityNodeInfo.ACTION_CLEAR_ACCESSIBILITY_FOCUS);
}
@@ -6069,7 +6147,7 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
return;
}
if ((focusableMode & FOCUSABLES_ACCESSIBILITY) == FOCUSABLES_ACCESSIBILITY) {
- if (canTakeAccessibilityFocusFromHover() || getAccessibilityNodeProvider() != null) {
+ if (isAccessibilityFocusable()) {
views.add(this);
return;
}
@@ -6202,7 +6280,7 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUS_CLEARED);
notifyAccessibilityStateChanged();
// Clear the text navigation state.
- setAccessibilityCursorPosition(-1);
+ setAccessibilityCursorPosition(ACCESSIBILITY_CURSOR_POSITION_UNDEFINED);
}
// Clear the global reference of accessibility focus if this
// view or any of its descendants had accessibility focus.
@@ -6252,6 +6330,7 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
void clearAccessibilityFocusNoCallbacks() {
if ((mPrivateFlags2 & ACCESSIBILITY_FOCUSED) != 0) {
mPrivateFlags2 &= ~ACCESSIBILITY_FOCUSED;
+ setAccessibilityCursorPosition(ACCESSIBILITY_CURSOR_POSITION_UNDEFINED);
invalidate();
}
}
@@ -6403,12 +6482,9 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
* @see #IMPORTANT_FOR_ACCESSIBILITY_AUTO
*/
@ViewDebug.ExportedProperty(category = "accessibility", mapping = {
- @ViewDebug.IntToString(from = IMPORTANT_FOR_ACCESSIBILITY_AUTO,
- to = "IMPORTANT_FOR_ACCESSIBILITY_AUTO"),
- @ViewDebug.IntToString(from = IMPORTANT_FOR_ACCESSIBILITY_YES,
- to = "IMPORTANT_FOR_ACCESSIBILITY_YES"),
- @ViewDebug.IntToString(from = IMPORTANT_FOR_ACCESSIBILITY_NO,
- to = "IMPORTANT_FOR_ACCESSIBILITY_NO")
+ @ViewDebug.IntToString(from = IMPORTANT_FOR_ACCESSIBILITY_AUTO, to = "auto"),
+ @ViewDebug.IntToString(from = IMPORTANT_FOR_ACCESSIBILITY_YES, to = "yes"),
+ @ViewDebug.IntToString(from = IMPORTANT_FOR_ACCESSIBILITY_NO, to = "no")
})
public int getImportantForAccessibility() {
return (mPrivateFlags2 & IMPORTANT_FOR_ACCESSIBILITY_MASK)
@@ -6461,6 +6537,73 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
}
/**
+ * Gets the mode for determining whether this View can take accessibility focus.
+ *
+ * @return The mode for determining whether a View can take accessibility focus.
+ *
+ * @attr ref android.R.styleable#View_accessibilityFocusable
+ *
+ * @see #ACCESSIBILITY_FOCUSABLE_YES
+ * @see #ACCESSIBILITY_FOCUSABLE_NO
+ * @see #ACCESSIBILITY_FOCUSABLE_AUTO
+ *
+ * @hide
+ */
+ @ViewDebug.ExportedProperty(category = "accessibility", mapping = {
+ @ViewDebug.IntToString(from = ACCESSIBILITY_FOCUSABLE_AUTO, to = "auto"),
+ @ViewDebug.IntToString(from = ACCESSIBILITY_FOCUSABLE_YES, to = "yes"),
+ @ViewDebug.IntToString(from = ACCESSIBILITY_FOCUSABLE_NO, to = "no")
+ })
+ public int getAccessibilityFocusable() {
+ return (mPrivateFlags2 & ACCESSIBILITY_FOCUSABLE_MASK) >>> ACCESSIBILITY_FOCUSABLE_SHIFT;
+ }
+
+ /**
+ * Sets how to determine whether this view can take accessibility focus.
+ *
+ * @param mode How to determine whether this view can take accessibility focus.
+ *
+ * @attr ref android.R.styleable#View_accessibilityFocusable
+ *
+ * @see #ACCESSIBILITY_FOCUSABLE_YES
+ * @see #ACCESSIBILITY_FOCUSABLE_NO
+ * @see #ACCESSIBILITY_FOCUSABLE_AUTO
+ *
+ * @hide
+ */
+ public void setAccessibilityFocusable(int mode) {
+ if (mode != getAccessibilityFocusable()) {
+ mPrivateFlags2 &= ~ACCESSIBILITY_FOCUSABLE_MASK;
+ mPrivateFlags2 |= (mode << ACCESSIBILITY_FOCUSABLE_SHIFT)
+ & ACCESSIBILITY_FOCUSABLE_MASK;
+ notifyAccessibilityStateChanged();
+ }
+ }
+
+ /**
+ * Gets whether this view can take accessibility focus.
+ *
+ * @return Whether the view can take accessibility focus.
+ *
+ * @hide
+ */
+ public boolean isAccessibilityFocusable() {
+ final int mode = (mPrivateFlags2 & ACCESSIBILITY_FOCUSABLE_MASK)
+ >>> ACCESSIBILITY_FOCUSABLE_SHIFT;
+ switch (mode) {
+ case ACCESSIBILITY_FOCUSABLE_YES:
+ return true;
+ case ACCESSIBILITY_FOCUSABLE_NO:
+ return false;
+ case ACCESSIBILITY_FOCUSABLE_AUTO:
+ return canTakeAccessibilityFocusFromHover()
+ || getAccessibilityNodeProvider() != null;
+ default:
+ throw new IllegalArgumentException("Unknow accessibility focusable mode: " + mode);
+ }
+ }
+
+ /**
* Gets the parent for accessibility purposes. Note that the parent for
* accessibility is not necessary the immediate parent. It is the first
* predecessor that is important for accessibility.
@@ -6641,7 +6784,10 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
}
} break;
case AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS: {
- if (!isAccessibilityFocused()) {
+ final int mode = getAccessibilityFocusable();
+ if (!isAccessibilityFocused()
+ && (mode == ACCESSIBILITY_FOCUSABLE_YES
+ || mode == ACCESSIBILITY_FOCUSABLE_AUTO)) {
return requestAccessibilityFocus();
}
} break;
@@ -6681,12 +6827,11 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
final int current = getAccessibilityCursorPosition();
final int[] range = iterator.following(current);
if (range == null) {
- setAccessibilityCursorPosition(-1);
return false;
}
final int start = range[0];
final int end = range[1];
- setAccessibilityCursorPosition(start);
+ setAccessibilityCursorPosition(end);
sendViewTextTraversedAtGranularityEvent(
AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY,
granularity, start, end);
@@ -6702,16 +6847,26 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
if (iterator == null) {
return false;
}
- final int selectionStart = getAccessibilityCursorPosition();
- final int current = selectionStart >= 0 ? selectionStart : text.length() + 1;
+ int current = getAccessibilityCursorPosition();
+ if (current == ACCESSIBILITY_CURSOR_POSITION_UNDEFINED) {
+ current = text.length();
+ } else if (granularity == AccessibilityNodeInfo.MOVEMENT_GRANULARITY_CHARACTER) {
+ // When traversing by character we always put the cursor after the character
+ // to ease edit and have to compensate before asking the for previous segment.
+ current--;
+ }
final int[] range = iterator.preceding(current);
if (range == null) {
- setAccessibilityCursorPosition(-1);
return false;
}
final int start = range[0];
final int end = range[1];
- setAccessibilityCursorPosition(end);
+ // Always put the cursor after the character to ease edit.
+ if (granularity == AccessibilityNodeInfo.MOVEMENT_GRANULARITY_CHARACTER) {
+ setAccessibilityCursorPosition(end);
+ } else {
+ setAccessibilityCursorPosition(start);
+ }
sendViewTextTraversedAtGranularityEvent(
AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY,
granularity, start, end);
@@ -7389,6 +7544,10 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
* when {@link KeyEvent#KEYCODE_DPAD_CENTER} or {@link KeyEvent#KEYCODE_ENTER}
* is released, if the view is enabled and clickable.
*
+ * <p>Key presses in software keyboards will generally NOT trigger this listener,
+ * although some may elect to do so in some situations. Do not rely on this to
+ * catch software key presses.
+ *
* @param keyCode A key code that represents the button pressed, from
* {@link android.view.KeyEvent}.
* @param event The KeyEvent object that defines the button action.
@@ -7420,6 +7579,9 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
* Default implementation of {@link KeyEvent.Callback#onKeyLongPress(int, KeyEvent)
* KeyEvent.Callback.onKeyLongPress()}: always returns false (doesn't handle
* the event).
+ * <p>Key presses in software keyboards will generally NOT trigger this listener,
+ * although some may elect to do so in some situations. Do not rely on this to
+ * catch software key presses.
*/
public boolean onKeyLongPress(int keyCode, KeyEvent event) {
return false;
@@ -7430,6 +7592,9 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
* KeyEvent.Callback.onKeyUp()}: perform clicking of the view
* when {@link KeyEvent#KEYCODE_DPAD_CENTER} or
* {@link KeyEvent#KEYCODE_ENTER} is released.
+ * <p>Key presses in software keyboards will generally NOT trigger this listener,
+ * although some may elect to do so in some situations. Do not rely on this to
+ * catch software key presses.
*
* @param keyCode A key code that represents the button pressed, from
* {@link android.view.KeyEvent}.
@@ -7464,6 +7629,9 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
* Default implementation of {@link KeyEvent.Callback#onKeyMultiple(int, int, KeyEvent)
* KeyEvent.Callback.onKeyMultiple()}: always returns false (doesn't handle
* the event).
+ * <p>Key presses in software keyboards will generally NOT trigger this listener,
+ * although some may elect to do so in some situations. Do not rely on this to
+ * catch software key presses.
*
* @param keyCode A key code that represents the button pressed, from
* {@link android.view.KeyEvent}.
@@ -8023,6 +8191,7 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
private void removeSendViewScrolledAccessibilityEventCallback() {
if (mSendViewScrolledAccessibilityEvent != null) {
removeCallbacks(mSendViewScrolledAccessibilityEvent);
+ mSendViewScrolledAccessibilityEvent.mIsPending = false;
}
}
@@ -16760,14 +16929,20 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
}
/**
- * Interface definition for a callback to be invoked when a key event is
- * dispatched to this view. The callback will be invoked before the key
- * event is given to the view.
+ * Interface definition for a callback to be invoked when a hardware key event is
+ * dispatched to this view. The callback will be invoked before the key event is
+ * given to the view. This is only useful for hardware keyboards; a software input
+ * method has no obligation to trigger this listener.
*/
public interface OnKeyListener {
/**
- * Called when a key is dispatched to a view. This allows listeners to
+ * Called when a hardware key is dispatched to a view. This allows listeners to
* get a chance to respond before the target view.
+ * <p>Key presses in software keyboards will generally NOT trigger this method,
+ * although some may elect to do so in some situations. Do not assume a
+ * software input method has to be key-based; even if it is, it may use key presses
+ * in a different way than you expect, so there is no way to reliably catch soft
+ * input key presses.
*
* @param v The view the key has been dispatched to.
* @param keyCode The code for the physical key that was pressed
diff --git a/core/java/android/view/inputmethod/InputConnection.java b/core/java/android/view/inputmethod/InputConnection.java
index 3563d4d..76c6d19 100644
--- a/core/java/android/view/inputmethod/InputConnection.java
+++ b/core/java/android/view/inputmethod/InputConnection.java
@@ -283,7 +283,7 @@ public interface InputConnection {
/**
* Tell the editor that you are done with a batch edit previously
- * initiated with {@link #endBatchEdit}.
+ * initiated with {@link #beginBatchEdit}.
*/
public boolean endBatchEdit();
@@ -307,7 +307,11 @@ public interface InputConnection {
* {@link KeyEvent#FLAG_SOFT_KEYBOARD KeyEvent.FLAG_SOFT_KEYBOARD} on all
* key event objects you give to this API; the flag will not be set
* for you.
- *
+ *
+ * <p>Note that it's discouraged to send such key events in normal operation;
+ * this is mainly for use with {@link android.text.InputType#TYPE_NULL} type
+ * text fields. Use the {@link #commitText} family of methods to send text
+ * to the application instead.
* @param event The key event.
*
* @return Returns true on success, false if the input connection is no longer
diff --git a/core/java/android/view/textservice/TextServicesManager.java b/core/java/android/view/textservice/TextServicesManager.java
index fc59e6e..161e8fb 100644
--- a/core/java/android/view/textservice/TextServicesManager.java
+++ b/core/java/android/view/textservice/TextServicesManager.java
@@ -217,7 +217,7 @@ public final class TextServicesManager {
public SpellCheckerSubtype getCurrentSpellCheckerSubtype(
boolean allowImplicitlySelectedSubtype) {
try {
- // Passing null as a locale for ICS
+ // Passing null as a locale until we support multiple enabled spell checker subtypes.
return sService.getCurrentSpellCheckerSubtype(null, allowImplicitlySelectedSubtype);
} catch (RemoteException e) {
Log.e(TAG, "Error in getCurrentSpellCheckerSubtype: " + e);
diff --git a/core/java/android/webkit/AutoCompletePopup.java b/core/java/android/webkit/AutoCompletePopup.java
index 87e878b..c624ce4 100644
--- a/core/java/android/webkit/AutoCompletePopup.java
+++ b/core/java/android/webkit/AutoCompletePopup.java
@@ -181,8 +181,11 @@ class AutoCompletePopup implements OnItemClickListener, Filter.FilterListener,
// There is no autofill profile setup yet and the user has
// elected to try and set one up. Call through to the
// embedder to action that.
- mWebView.getWebChromeClient().setupAutoFill(
+ WebChromeClient webChromeClient = mWebView.getWebChromeClient();
+ if (webChromeClient != null) {
+ webChromeClient.setupAutoFill(
mHandler.obtainMessage(AUTOFILL_FORM));
+ }
}
} else {
Object selectedItem;
diff --git a/core/java/android/webkit/WebViewClassic.java b/core/java/android/webkit/WebViewClassic.java
index f03fb86..65fd59a 100644
--- a/core/java/android/webkit/WebViewClassic.java
+++ b/core/java/android/webkit/WebViewClassic.java
@@ -4403,8 +4403,11 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc
if (mNativeClass == 0)
return;
boolean queueFull;
+ final int scrollingLayer = (mTouchMode == TOUCH_DRAG_LAYER_MODE)
+ ? mCurrentScrollingLayerId : 0;
queueFull = nativeSetBaseLayer(mNativeClass, layer,
- showVisualIndicator, isPictureAfterFirstLayout);
+ showVisualIndicator, isPictureAfterFirstLayout,
+ scrollingLayer);
if (queueFull) {
mWebViewCore.pauseWebKitDraw();
@@ -8515,7 +8518,8 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc
private native String nativeGetSelection();
private native void nativeSetHeightCanMeasure(boolean measure);
private native boolean nativeSetBaseLayer(int nativeInstance,
- int layer, boolean showVisualIndicator, boolean isPictureAfterFirstLayout);
+ int layer, boolean showVisualIndicator, boolean isPictureAfterFirstLayout,
+ int scrollingLayer);
private native int nativeGetBaseLayer(int nativeInstance);
private native void nativeCopyBaseContentToPicture(Picture pict);
private native boolean nativeHasContent();
diff --git a/core/java/android/webkit/WebViewInputDispatcher.java b/core/java/android/webkit/WebViewInputDispatcher.java
index d8065e9..f64547f 100644
--- a/core/java/android/webkit/WebViewInputDispatcher.java
+++ b/core/java/android/webkit/WebViewInputDispatcher.java
@@ -661,6 +661,7 @@ final class WebViewInputDispatcher {
// Web kit has decided to consume the event!
if (d.mEventType == EVENT_TYPE_TOUCH) {
enqueueUiCancelTouchEventIfNeededLocked();
+ unscheduleLongPressLocked();
}
} else {
// Web kit is being friendly. Pass the event to the UI.
diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java
index 9abe72b..dae9c6a 100644
--- a/core/java/android/widget/AbsListView.java
+++ b/core/java/android/widget/AbsListView.java
@@ -2283,14 +2283,10 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
final ListAdapter adapter = getAdapter();
if ((position == INVALID_POSITION) || (adapter == null)) {
- // Cannot perform actions on invalid items.
- info.setEnabled(false);
return;
}
if (!isEnabled() || !adapter.isEnabled(position)) {
- // Cannot perform actions on invalid items.
- info.setEnabled(false);
return;
}
diff --git a/core/java/android/widget/AccessibilityIterators.java b/core/java/android/widget/AccessibilityIterators.java
index e800e8d..a3d58a4 100644
--- a/core/java/android/widget/AccessibilityIterators.java
+++ b/core/java/android/widget/AccessibilityIterators.java
@@ -56,16 +56,18 @@ final class AccessibilityIterators {
if (offset >= mText.length()) {
return null;
}
- int nextLine = -1;
+ int nextLine;
if (offset < 0) {
nextLine = mLayout.getLineForOffset(0);
} else {
final int currentLine = mLayout.getLineForOffset(offset);
- if (currentLine < mLayout.getLineCount() - 1) {
+ if (getLineEdgeIndex(currentLine, DIRECTION_START) == offset) {
+ nextLine = currentLine;
+ } else {
nextLine = currentLine + 1;
}
}
- if (nextLine < 0) {
+ if (nextLine >= mLayout.getLineCount()) {
return null;
}
final int start = getLineEdgeIndex(nextLine, DIRECTION_START);
@@ -82,12 +84,14 @@ final class AccessibilityIterators {
if (offset <= 0) {
return null;
}
- int previousLine = -1;
+ int previousLine;
if (offset > mText.length()) {
previousLine = mLayout.getLineForOffset(mText.length());
} else {
- final int currentLine = mLayout.getLineForOffset(offset - 1);
- if (currentLine > 0) {
+ final int currentLine = mLayout.getLineForOffset(offset);
+ if (getLineEdgeIndex(currentLine, DIRECTION_END) + 1 == offset) {
+ previousLine = currentLine;
+ } else {
previousLine = currentLine - 1;
}
}
@@ -141,29 +145,18 @@ final class AccessibilityIterators {
return null;
}
- final int currentLine = mLayout.getLineForOffset(offset);
+ final int start = Math.max(0, offset);
+
+ final int currentLine = mLayout.getLineForOffset(start);
final int currentLineTop = mLayout.getLineTop(currentLine);
final int pageHeight = mTempRect.height() - mView.getTotalPaddingTop()
- mView.getTotalPaddingBottom();
+ final int nextPageStartY = currentLineTop + pageHeight;
+ final int lastLineTop = mLayout.getLineTop(mLayout.getLineCount() - 1);
+ final int currentPageEndLine = (nextPageStartY < lastLineTop)
+ ? mLayout.getLineForVertical(nextPageStartY) - 1 : mLayout.getLineCount() - 1;
- final int nextPageStartLine;
- final int nextPageEndLine;
- if (offset < 0) {
- nextPageStartLine = currentLine;
- final int nextPageEndY = currentLineTop + pageHeight;
- nextPageEndLine = mLayout.getLineForVertical(nextPageEndY);
- } else {
- final int nextPageStartY = currentLineTop + pageHeight;
- nextPageStartLine = mLayout.getLineForVertical(nextPageStartY) + 1;
- if (mLayout.getLineTop(nextPageStartLine) <= nextPageStartY) {
- return null;
- }
- final int nextPageEndY = nextPageStartY + pageHeight;
- nextPageEndLine = mLayout.getLineForVertical(nextPageEndY);
- }
-
- final int start = getLineEdgeIndex(nextPageStartLine, DIRECTION_START);
- final int end = getLineEdgeIndex(nextPageEndLine, DIRECTION_END) + 1;
+ final int end = getLineEdgeIndex(currentPageEndLine, DIRECTION_END) + 1;
return getRange(start, end);
}
@@ -181,37 +174,17 @@ final class AccessibilityIterators {
return null;
}
- final int currentLine = mLayout.getLineForOffset(offset);
+ final int end = Math.min(mText.length(), offset);
+
+ final int currentLine = mLayout.getLineForOffset(end);
final int currentLineTop = mLayout.getLineTop(currentLine);
final int pageHeight = mTempRect.height() - mView.getTotalPaddingTop()
- mView.getTotalPaddingBottom();
+ final int previousPageEndY = currentLineTop - pageHeight;
+ final int currentPageStartLine = (previousPageEndY > 0) ?
+ mLayout.getLineForVertical(previousPageEndY) + 1 : 0;
- final int previousPageStartLine;
- final int previousPageEndLine;
- if (offset > mText.length()) {
- final int prevousPageStartY = mLayout.getHeight() - pageHeight;
- if (prevousPageStartY < 0) {
- return null;
- }
- previousPageStartLine = mLayout.getLineForVertical(prevousPageStartY);
- previousPageEndLine = mLayout.getLineCount() - 1;
- } else {
- final int prevousPageStartY;
- if (offset == mText.length()) {
- prevousPageStartY = mLayout.getHeight() - 2 * pageHeight;
- } else {
- prevousPageStartY = currentLineTop - 2 * pageHeight;
- }
- if (prevousPageStartY < 0) {
- return null;
- }
- previousPageStartLine = mLayout.getLineForVertical(prevousPageStartY);
- final int previousPageEndY = prevousPageStartY + pageHeight;
- previousPageEndLine = mLayout.getLineForVertical(previousPageEndY) - 1;
- }
-
- final int start = getLineEdgeIndex(previousPageStartLine, DIRECTION_START);
- final int end = getLineEdgeIndex(previousPageEndLine, DIRECTION_END) + 1;
+ final int start = getLineEdgeIndex(currentPageStartLine, DIRECTION_START);
return getRange(start, end);
}
diff --git a/core/java/android/widget/Editor.java b/core/java/android/widget/Editor.java
index 16490e8..c29dd58 100644
--- a/core/java/android/widget/Editor.java
+++ b/core/java/android/widget/Editor.java
@@ -1416,6 +1416,7 @@ public class Editor {
}
Layout layout = mTextView.getLayout();
+ Layout hintLayout = mTextView.getHintLayout();
final int offset = mTextView.getSelectionStart();
final int line = layout.getLineForOffset(offset);
final int top = layout.getLineTop(line);
@@ -1429,13 +1430,23 @@ public class Editor {
middle = (top + bottom) >> 1;
}
- updateCursorPosition(0, top, middle, layout.getPrimaryHorizontal(offset));
+ updateCursorPosition(0, top, middle, getPrimaryHorizontal(layout, hintLayout, offset));
if (mCursorCount == 2) {
updateCursorPosition(1, middle, bottom, layout.getSecondaryHorizontal(offset));
}
}
+ private float getPrimaryHorizontal(Layout layout, Layout hintLayout, int offset) {
+ if (TextUtils.isEmpty(layout.getText()) &&
+ hintLayout != null &&
+ !TextUtils.isEmpty(hintLayout.getText())) {
+ return hintLayout.getPrimaryHorizontal(offset);
+ } else {
+ return layout.getPrimaryHorizontal(offset);
+ }
+ }
+
/**
* @return true if the selection mode was actually started.
*/
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index bd19f00..131b075 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -1312,6 +1312,14 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
}
/**
+ * @return the Layout that is currently being used to display the hint text.
+ * This can be null.
+ */
+ final Layout getHintLayout() {
+ return mHintLayout;
+ }
+
+ /**
* @return the current key listener for this TextView.
* This will frequently be null for non-EditText TextViews.
*
@@ -8376,10 +8384,12 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
@Override
public int getAccessibilityCursorPosition() {
if (TextUtils.isEmpty(getContentDescription())) {
- return getSelectionEnd();
- } else {
- return super.getAccessibilityCursorPosition();
+ final int selectionEnd = getSelectionEnd();
+ if (selectionEnd >= 0) {
+ return selectionEnd;
+ }
}
+ return super.getAccessibilityCursorPosition();
}
/**
@@ -8391,7 +8401,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
return;
}
if (TextUtils.isEmpty(getContentDescription())) {
- if (index >= 0) {
+ if (index >= 0 && index <= mText.length()) {
Selection.setSelection((Spannable) mText, index);
} else {
Selection.removeSelection((Spannable) mText);
diff --git a/core/java/com/android/internal/app/ActionBarImpl.java b/core/java/com/android/internal/app/ActionBarImpl.java
index 234cb71..46478ca 100644
--- a/core/java/com/android/internal/app/ActionBarImpl.java
+++ b/core/java/com/android/internal/app/ActionBarImpl.java
@@ -673,26 +673,29 @@ public class ActionBarImpl extends ActionBar {
if (mCurWindowVisibility == View.VISIBLE && (mShowHideAnimationEnabled
|| fromSystem)) {
- mTopVisibilityView.setAlpha(0);
- mTopVisibilityView.setTranslationY(-mTopVisibilityView.getHeight());
+ mTopVisibilityView.setTranslationY(0); // because we're about to ask its window loc
+ float startingY = -mTopVisibilityView.getHeight();
+ if (fromSystem) {
+ int topLeft[] = {0, 0};
+ mTopVisibilityView.getLocationInWindow(topLeft);
+ startingY -= topLeft[1];
+ }
+ mTopVisibilityView.setTranslationY(startingY);
AnimatorSet anim = new AnimatorSet();
- AnimatorSet.Builder b = anim.play(ObjectAnimator.ofFloat(mTopVisibilityView, "alpha", 1));
- b.with(ObjectAnimator.ofFloat(mTopVisibilityView, "translationY", 0));
+ AnimatorSet.Builder b = anim.play(ObjectAnimator.ofFloat(mTopVisibilityView,
+ "translationY", 0));
if (mContentView != null) {
b.with(ObjectAnimator.ofFloat(mContentView, "translationY",
- -mTopVisibilityView.getHeight(), 0));
+ startingY, 0));
}
if (mSplitView != null && mContextDisplayMode == CONTEXT_DISPLAY_SPLIT) {
- mSplitView.setAlpha(0);
mSplitView.setTranslationY(mSplitView.getHeight());
mSplitView.setVisibility(View.VISIBLE);
- b.with(ObjectAnimator.ofFloat(mSplitView, "alpha", 1));
b.with(ObjectAnimator.ofFloat(mSplitView, "translationY", 0));
}
anim.setInterpolator(AnimationUtils.loadInterpolator(mContext,
- com.android.internal.R.interpolator.decelerate_quad));
- anim.setDuration(mContext.getResources().getInteger(
- com.android.internal.R.integer.config_mediumAnimTime));
+ com.android.internal.R.interpolator.decelerate_cubic));
+ anim.setDuration(250);
// If this is being shown from the system, add a small delay.
// This is because we will also be animating in the status bar,
// and these two elements can't be done in lock-step. So we give
@@ -700,9 +703,6 @@ public class ActionBarImpl extends ActionBar {
// the action bar animates. (This corresponds to the corresponding
// case when hiding, where the status bar has a small delay before
// starting.)
- if (fromSystem) {
- anim.setStartDelay(100);
- }
anim.addListener(mShowListener);
mCurrentShowAnim = anim;
anim.start();
@@ -734,23 +734,26 @@ public class ActionBarImpl extends ActionBar {
mTopVisibilityView.setAlpha(1);
mContainerView.setTransitioning(true);
AnimatorSet anim = new AnimatorSet();
- AnimatorSet.Builder b = anim.play(ObjectAnimator.ofFloat(mTopVisibilityView, "alpha", 0));
- b.with(ObjectAnimator.ofFloat(mTopVisibilityView, "translationY",
- -mTopVisibilityView.getHeight()));
+ float endingY = -mTopVisibilityView.getHeight();
+ if (fromSystem) {
+ int topLeft[] = {0, 0};
+ mTopVisibilityView.getLocationInWindow(topLeft);
+ endingY -= topLeft[1];
+ }
+ AnimatorSet.Builder b = anim.play(ObjectAnimator.ofFloat(mTopVisibilityView,
+ "translationY", endingY));
if (mContentView != null) {
b.with(ObjectAnimator.ofFloat(mContentView, "translationY",
- 0, -mTopVisibilityView.getHeight()));
+ 0, endingY));
}
if (mSplitView != null && mSplitView.getVisibility() == View.VISIBLE) {
mSplitView.setAlpha(1);
- b.with(ObjectAnimator.ofFloat(mSplitView, "alpha", 0));
b.with(ObjectAnimator.ofFloat(mSplitView, "translationY",
mSplitView.getHeight()));
}
anim.setInterpolator(AnimationUtils.loadInterpolator(mContext,
- com.android.internal.R.interpolator.accelerate_quad));
- anim.setDuration(mContext.getResources().getInteger(
- com.android.internal.R.integer.config_mediumAnimTime));
+ com.android.internal.R.interpolator.accelerate_cubic));
+ anim.setDuration(250);
anim.addListener(mHideListener);
mCurrentShowAnim = anim;
anim.start();
diff --git a/core/java/com/android/internal/widget/multiwaveview/MultiWaveView.java b/core/java/com/android/internal/widget/multiwaveview/MultiWaveView.java
index 8cd63ef..b2c3091 100644
--- a/core/java/com/android/internal/widget/multiwaveview/MultiWaveView.java
+++ b/core/java/com/android/internal/widget/multiwaveview/MultiWaveView.java
@@ -19,6 +19,7 @@ package com.android.internal.widget.multiwaveview;
import android.animation.Animator;
import android.animation.Animator.AnimatorListener;
import android.animation.AnimatorListenerAdapter;
+import android.animation.ObjectAnimator;
import android.animation.TimeInterpolator;
import android.animation.ValueAnimator;
import android.animation.ValueAnimator.AnimatorUpdateListener;
@@ -27,6 +28,7 @@ import android.content.res.Resources;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.RectF;
+import android.graphics.drawable.Drawable;
import android.os.Vibrator;
import android.text.TextUtils;
import android.util.AttributeSet;
@@ -52,10 +54,11 @@ public class MultiWaveView extends View {
// Wave state machine
private static final int STATE_IDLE = 0;
- private static final int STATE_FIRST_TOUCH = 1;
- private static final int STATE_TRACKING = 2;
- private static final int STATE_SNAP = 3;
- private static final int STATE_FINISH = 4;
+ private static final int STATE_START = 1;
+ private static final int STATE_FIRST_TOUCH = 2;
+ private static final int STATE_TRACKING = 3;
+ private static final int STATE_SNAP = 4;
+ private static final int STATE_FINISH = 5;
// Animation properties.
private static final float SNAP_MARGIN_DEFAULT = 20.0f; // distance to ring before we snap to it
@@ -74,17 +77,18 @@ public class MultiWaveView extends View {
private static final int CHEVRON_INCREMENTAL_DELAY = 160;
private static final int CHEVRON_ANIMATION_DURATION = 850;
private static final int RETURN_TO_HOME_DELAY = 1200;
- private static final int RETURN_TO_HOME_DURATION = 300;
+ private static final int RETURN_TO_HOME_DURATION = 200;
private static final int HIDE_ANIMATION_DELAY = 200;
private static final int HIDE_ANIMATION_DURATION = 200;
private static final int SHOW_ANIMATION_DURATION = 200;
private static final int SHOW_ANIMATION_DELAY = 50;
+ private static final int INITIAL_SHOW_HANDLE_DURATION = 200;
+
private static final float TAP_RADIUS_SCALE_ACCESSIBILITY_ENABLED = 1.3f;
- private static final float TARGET_SCALE_SELECTED = 0.8f;
- private static final long INITIAL_SHOW_HANDLE_DURATION = 200;
- private static final float TARGET_SCALE_UNSELECTED = 1.0f;
- private static final float RING_SCALE_UNSELECTED = 0.5f;
- private static final float RING_SCALE_SELECTED = 1.5f;
+ private static final float TARGET_SCALE_EXPANDED = 1.0f;
+ private static final float TARGET_SCALE_COLLAPSED = 0.8f;
+ private static final float RING_SCALE_EXPANDED = 1.0f;
+ private static final float RING_SCALE_COLLAPSED = 0.5f;
private TimeInterpolator mChevronAnimationInterpolator = Ease.Quad.easeOut;
@@ -182,7 +186,7 @@ public class MultiWaveView extends View {
if (mNewTargetResources != 0) {
internalSetTargetResources(mNewTargetResources);
mNewTargetResources = 0;
- hideTargets(false);
+ hideTargets(false, false);
}
mAnimatingTargets = false;
}
@@ -195,6 +199,7 @@ public class MultiWaveView extends View {
private int mVerticalInset;
private int mGravity = Gravity.TOP;
private boolean mInitialLayout = true;
+ private Tweener mBackgroundAnimator;
public MultiWaveView(Context context) {
this(context, null);
@@ -358,14 +363,21 @@ public class MultiWaveView extends View {
switch (state) {
case STATE_IDLE:
deactivateTargets();
+ hideTargets(true, false);
+ startBackgroundAnimation(0, 0.0f);
mHandleDrawable.setState(TargetDrawable.STATE_INACTIVE);
break;
+ case STATE_START:
+ deactivateHandle(0, 0, 1.0f, null);
+ startBackgroundAnimation(0, 0.0f);
+ break;
+
case STATE_FIRST_TOUCH:
- stopHandleAnimation();
deactivateTargets();
showTargets(true);
- activateHandle();
+ mHandleDrawable.setState(TargetDrawable.STATE_ACTIVE);
+ startBackgroundAnimation(INITIAL_SHOW_HANDLE_DURATION, 1.0f);
setGrabbedState(OnTriggerListener.CENTER_HANDLE);
if (AccessibilityManager.getInstance(mContext).isEnabled()) {
announceTargets();
@@ -384,17 +396,30 @@ public class MultiWaveView extends View {
}
}
- private void activateHandle() {
- mHandleDrawable.setState(TargetDrawable.STATE_ACTIVE);
- if (mAlwaysTrackFinger) {
- mHandleAnimations.stop();
- mHandleDrawable.setAlpha(0.0f);
- mHandleAnimations.add(Tweener.to(mHandleDrawable, INITIAL_SHOW_HANDLE_DURATION,
- "ease", Ease.Cubic.easeIn,
- "alpha", 1.0f,
- "onUpdate", mUpdateListener));
- mHandleAnimations.start();
- }
+ private void activateHandle(int duration, int delay, float finalAlpha,
+ AnimatorListener finishListener) {
+ mHandleAnimations.cancel();
+ mHandleAnimations.add(Tweener.to(mHandleDrawable, duration,
+ "ease", Ease.Cubic.easeIn,
+ "delay", delay,
+ "alpha", finalAlpha,
+ "onUpdate", mUpdateListener,
+ "onComplete", finishListener));
+ mHandleAnimations.start();
+ }
+
+ private void deactivateHandle(int duration, int delay, float finalAlpha,
+ AnimatorListener finishListener) {
+ mHandleAnimations.cancel();
+ mHandleAnimations.add(Tweener.to(mHandleDrawable, duration,
+ "ease", Ease.Quart.easeOut,
+ "delay", delay,
+ "alpha", finalAlpha,
+ "x", 0,
+ "y", 0,
+ "onUpdate", mUpdateListener,
+ "onComplete", finishListener));
+ mHandleAnimations.start();
}
/**
@@ -441,14 +466,6 @@ public class MultiWaveView extends View {
mChevronAnimations.start();
}
- private void stopChevronAnimation() {
- mChevronAnimations.stop();
- }
-
- private void stopHandleAnimation() {
- mHandleAnimations.stop();
- }
-
private void deactivateTargets() {
final int count = mTargetDrawables.size();
for (int i = 0; i < count; i++) {
@@ -493,58 +510,53 @@ public class MultiWaveView extends View {
private void doFinish() {
final int activeTarget = mActiveTarget;
- boolean targetHit = activeTarget != -1;
-
- // Hide unselected targets
- hideTargets(true);
+ final boolean targetHit = activeTarget != -1;
- // Highlight the selected one
- mHandleAnimations.cancel();
if (targetHit) {
- mHandleDrawable.setAlpha(0.0f);
- mTargetDrawables.get(activeTarget).setState(TargetDrawable.STATE_ACTIVE);
- hideUnselected(activeTarget);
+ if (DEBUG) Log.v(TAG, "Finish with target hit = " + targetHit);
+
+ highlightSelected(activeTarget);
// Inform listener of any active targets. Typically only one will be active.
- if (DEBUG) Log.v(TAG, "Finish with target hit = " + targetHit);
+ deactivateHandle(RETURN_TO_HOME_DURATION, RETURN_TO_HOME_DELAY, 0.0f, mResetListener);
dispatchTriggerEvent(activeTarget);
+ if (!mAlwaysTrackFinger) {
+ // Force ring and targets to finish animation to final expanded state
+ mTargetAnimations.stop();
+ }
+ } else {
+ // Animate handle back to the center based on current state.
+ deactivateHandle(HIDE_ANIMATION_DURATION, HIDE_ANIMATION_DELAY, 1.0f,
+ mResetListenerWithPing);
+ hideTargets(true, false);
}
- // Animate handle back to the center based on current state.
- int delay = targetHit ? RETURN_TO_HOME_DELAY : 0;
- int duration = RETURN_TO_HOME_DURATION;
- mHandleAnimations.add(Tweener.to(mHandleDrawable, duration,
- "ease", Ease.Quart.easeOut,
- "delay", delay,
- "alpha", mAlwaysTrackFinger ? 0.0f : 1.0f,
- "x", 0,
- "y", 0,
- "onUpdate", mUpdateListener,
- "onComplete", (mDragging && !targetHit) ? mResetListenerWithPing : mResetListener));
- mHandleAnimations.start();
-
setGrabbedState(OnTriggerListener.NO_HANDLE);
}
+ private void highlightSelected(int activeTarget) {
+ // Highlight the given target and fade others
+ mTargetDrawables.get(activeTarget).setState(TargetDrawable.STATE_ACTIVE);
+ hideUnselected(activeTarget);
+ }
+
private void hideUnselected(int active) {
for (int i = 0; i < mTargetDrawables.size(); i++) {
if (i != active) {
mTargetDrawables.get(i).setAlpha(0.0f);
}
}
- mOuterRing.setAlpha(0.0f);
}
- private void hideTargets(boolean animate) {
+ private void hideTargets(boolean animate, boolean expanded) {
mTargetAnimations.cancel();
// Note: these animations should complete at the same time so that we can swap out
// the target assets asynchronously from the setTargetResources() call.
mAnimatingTargets = animate;
final int duration = animate ? HIDE_ANIMATION_DURATION : 0;
final int delay = animate ? HIDE_ANIMATION_DELAY : 0;
- final boolean targetSelected = mActiveTarget != -1;
- final float targetScale = targetSelected ? TARGET_SCALE_SELECTED : TARGET_SCALE_UNSELECTED;
+ final float targetScale = expanded ? TARGET_SCALE_EXPANDED : TARGET_SCALE_COLLAPSED;
final int length = mTargetDrawables.size();
for (int i = 0; i < length; i++) {
TargetDrawable target = mTargetDrawables.get(i);
@@ -558,7 +570,7 @@ public class MultiWaveView extends View {
"onUpdate", mUpdateListener));
}
- final float ringScaleTarget = targetSelected ? RING_SCALE_SELECTED : RING_SCALE_UNSELECTED;
+ final float ringScaleTarget = expanded ? RING_SCALE_EXPANDED : RING_SCALE_COLLAPSED;
mTargetAnimations.add(Tweener.to(mOuterRing, duration,
"ease", Ease.Cubic.easeOut,
"alpha", 0.0f,
@@ -580,8 +592,6 @@ public class MultiWaveView extends View {
for (int i = 0; i < length; i++) {
TargetDrawable target = mTargetDrawables.get(i);
target.setState(TargetDrawable.STATE_INACTIVE);
- target.setScaleX(TARGET_SCALE_SELECTED);
- target.setScaleY(TARGET_SCALE_SELECTED);
mTargetAnimations.add(Tweener.to(target, duration,
"ease", Ease.Cubic.easeOut,
"alpha", 1.0f,
@@ -732,17 +742,30 @@ public class MultiWaveView extends View {
* @param animate
*/
public void reset(boolean animate) {
- stopChevronAnimation();
- stopHandleAnimation();
+ mChevronAnimations.stop();
+ mHandleAnimations.stop();
mTargetAnimations.stop();
+ startBackgroundAnimation(0, 0.0f);
hideChevrons();
- hideTargets(animate);
- mHandleDrawable.setX(0);
- mHandleDrawable.setY(0);
- mHandleDrawable.setState(TargetDrawable.STATE_INACTIVE);
+ hideTargets(animate, false);
+ deactivateHandle(0, 0, 1.0f, null);
Tweener.reset();
}
+ private void startBackgroundAnimation(int duration, float alpha) {
+ Drawable background = getBackground();
+ if (mAlwaysTrackFinger && background != null) {
+ if (mBackgroundAnimator != null) {
+ mBackgroundAnimator.animator.end();
+ }
+ mBackgroundAnimator = Tweener.to(background, duration,
+ "ease", Ease.Cubic.easeIn,
+ "alpha", new int[] {0, (int)(255.0f * alpha)},
+ "delay", SHOW_ANIMATION_DELAY);
+ mBackgroundAnimator.animator.start();
+ }
+ }
+
@Override
public boolean onTouchEvent(MotionEvent event) {
final int action = event.getAction();
@@ -784,9 +807,11 @@ public class MultiWaveView extends View {
}
private void handleDown(MotionEvent event) {
- if (!trySwitchToFirstTouchState(event.getX(), event.getY())) {
+ float eventX = event.getX();
+ float eventY = event.getY();
+ switchToState(STATE_START, eventX, eventY);
+ if (!trySwitchToFirstTouchState(eventX, eventY)) {
mDragging = false;
- mTargetAnimations.cancel();
ping();
}
}
@@ -830,7 +855,9 @@ public class MultiWaveView extends View {
if (!mDragging) {
trySwitchToFirstTouchState(eventX, eventY);
- } else {
+ }
+
+ if (mDragging) {
if (singleTarget) {
// Snap to outer ring if there's only one target
float snapRadius = mOuterRadius - mSnapMargin;
@@ -865,17 +892,11 @@ public class MultiWaveView extends View {
if (activeTarget != -1) {
switchToState(STATE_SNAP, x,y);
TargetDrawable target = targets.get(activeTarget);
- float newX = singleTarget ? x : target.getX();
- float newY = singleTarget ? y : target.getY();
+ final float newX = singleTarget ? x : target.getX();
+ final float newY = singleTarget ? y : target.getY();
moveHandleTo(newX, newY, false);
- mHandleAnimations.cancel();
- mHandleDrawable.setAlpha(0.0f);
} else {
switchToState(STATE_TRACKING, x, y);
- if (mActiveTarget != -1) {
- mHandleAnimations.cancel();
- mHandleDrawable.setAlpha(1.0f);
- }
moveHandleTo(x, y, false);
}
@@ -900,6 +921,9 @@ public class MultiWaveView extends View {
String targetContentDescription = getTargetDescription(activeTarget);
announceText(targetContentDescription);
}
+ activateHandle(0, 0, 0.0f, null);
+ } else {
+ activateHandle(0, 0, 1.0f, null);
}
}
mActiveTarget = activeTarget;
@@ -1021,7 +1045,7 @@ public class MultiWaveView extends View {
if (mInitialLayout) {
hideChevrons();
- hideTargets(false);
+ hideTargets(false, false);
moveHandleTo(0, 0, false);
mInitialLayout = false;
}
diff --git a/core/java/com/android/internal/widget/multiwaveview/Tweener.java b/core/java/com/android/internal/widget/multiwaveview/Tweener.java
index 1d502ba..d559d9d 100644
--- a/core/java/com/android/internal/widget/multiwaveview/Tweener.java
+++ b/core/java/com/android/internal/widget/multiwaveview/Tweener.java
@@ -83,6 +83,9 @@ class Tweener {
} else if (value instanceof float[]) {
props.add(PropertyValuesHolder.ofFloat(key,
((float[])value)[0], ((float[])value)[1]));
+ } else if (value instanceof int[]) {
+ props.add(PropertyValuesHolder.ofInt(key,
+ ((int[])value)[0], ((int[])value)[1]));
} else if (value instanceof Number) {
float floatValue = ((Number)value).floatValue();
props.add(PropertyValuesHolder.ofFloat(key, floatValue));
diff --git a/core/jni/android_database_SQLiteConnection.cpp b/core/jni/android_database_SQLiteConnection.cpp
index 0777ea2..3bbb8bf 100644
--- a/core/jni/android_database_SQLiteConnection.cpp
+++ b/core/jni/android_database_SQLiteConnection.cpp
@@ -41,6 +41,20 @@
namespace android {
+/* Busy timeout in milliseconds.
+ * If another connection (possibly in another process) has the database locked for
+ * longer than this amount of time then SQLite will generate a SQLITE_BUSY error.
+ * The SQLITE_BUSY error is then raised as a SQLiteDatabaseLockedException.
+ *
+ * In ordinary usage, busy timeouts are quite rare. Most databases only ever
+ * have a single open connection at a time unless they are using WAL. When using
+ * WAL, a timeout could occur if one connection is busy performing an auto-checkpoint
+ * operation. The busy timeout needs to be long enough to tolerate slow I/O write
+ * operations but not so long as to cause the application to hang indefinitely if
+ * there is a problem acquiring a database lock.
+ */
+static const int BUSY_TIMEOUT_MS = 2500;
+
static struct {
jfieldID name;
jfieldID numArgs;
@@ -127,8 +141,8 @@ static jint nativeOpen(JNIEnv* env, jclass clazz, jstring pathStr, jint openFlag
return 0;
}
- // Set the default busy handler to retry for 1000ms and then return SQLITE_BUSY
- err = sqlite3_busy_timeout(db, 1000 /* ms */);
+ // Set the default busy handler to retry automatically before returning SQLITE_BUSY.
+ err = sqlite3_busy_timeout(db, BUSY_TIMEOUT_MS);
if (err != SQLITE_OK) {
throw_sqlite3_exception(env, db, "Could not set busy timeout");
sqlite3_close(db);
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index e3082ea..155e59c 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -1983,7 +1983,7 @@
<activity android:name="android.accounts.ChooseTypeAndAccountActivity"
android:excludeFromRecents="true"
android:exported="true"
- android:theme="@android:style/Theme.Holo.DialogWhenLarge.NoActionBar"
+ android:theme="@android:style/Theme.Holo.Dialog"
android:label="@string/choose_account_label"
android:process=":ui">
</activity>
diff --git a/core/res/res/anim-sw720dp/task_close_enter.xml b/core/res/res/anim-sw720dp/task_close_enter.xml
index 9a747a1..e25978b 100644
--- a/core/res/res/anim-sw720dp/task_close_enter.xml
+++ b/core/res/res/anim-sw720dp/task_close_enter.xml
@@ -23,20 +23,20 @@
<alpha android:fromAlpha="0" android:toAlpha="1.0"
android:fillEnabled="true" android:fillBefore="true" android:fillAfter="true"
android:interpolator="@interpolator/decelerate_quad"
- android:startOffset="300"
+ android:startOffset="500"
android:duration="400"/>
- <translate android:fromYDelta="-120%" android:toYDelta="0"
+ <translate android:fromYDelta="-50%" android:toYDelta="0"
android:fillEnabled="true" android:fillBefore="true" android:fillAfter="true"
android:interpolator="@interpolator/decelerate_quint"
- android:startOffset="300"
+ android:startOffset="500"
android:duration="400" />
- <scale android:fromXScale=".5" android:toXScale="1.0"
- android:fromYScale=".5" android:toYScale="1.0"
+ <scale android:fromXScale=".8" android:toXScale="1.0"
+ android:fromYScale=".8" android:toYScale="1.0"
android:pivotX="50%p" android:pivotY="0%p"
android:fillEnabled="true" android:fillBefore="true" android:fillAfter="true"
android:interpolator="@interpolator/decelerate_quad"
- android:startOffset="300"
+ android:startOffset="500"
android:duration="400" />
</set> \ No newline at end of file
diff --git a/core/res/res/anim-sw720dp/task_close_exit.xml b/core/res/res/anim-sw720dp/task_close_exit.xml
index 35b1aa3..2d7e2a6 100644
--- a/core/res/res/anim-sw720dp/task_close_exit.xml
+++ b/core/res/res/anim-sw720dp/task_close_exit.xml
@@ -23,21 +23,21 @@
<alpha android:fromAlpha="1.0" android:toAlpha="0"
android:fillEnabled="true" android:fillBefore="true" android:fillAfter="true"
android:interpolator="@interpolator/accelerate_quad"
- android:duration="300"/>
+ android:duration="350"/>
- <translate android:fromYDelta="0" android:toYDelta="120%"
+ <translate android:fromYDelta="0" android:toYDelta="50%"
android:fillEnabled="true" android:fillBefore="true" android:fillAfter="true"
android:interpolator="@interpolator/accelerate_cubic"
- android:duration="300"/>
+ android:duration="350"/>
- <scale android:fromXScale="1.0" android:toXScale="0.5"
- android:fromYScale="1.0" android:toYScale="0.5"
+ <scale android:fromXScale="1.0" android:toXScale="0.8"
+ android:fromYScale="1.0" android:toYScale="0.8"
android:fillEnabled="true" android:fillBefore="true" android:fillAfter="true"
android:pivotX="50%p" android:pivotY="100%p"
android:interpolator="@interpolator/accelerate_quad"
- android:duration="300" />
+ android:duration="350" />
- <!-- This is needed to keep the animation running while task_open_enter completes -->
+ <!-- This is needed to keep the animation running while task_close_enter completes -->
<alpha android:fromAlpha="1.0" android:toAlpha="1.0"
- android:duration="700" />
+ android:duration="900" />
</set> \ No newline at end of file
diff --git a/core/res/res/anim-sw720dp/task_open_enter.xml b/core/res/res/anim-sw720dp/task_open_enter.xml
index 5e4ae18..d583b6e 100644
--- a/core/res/res/anim-sw720dp/task_open_enter.xml
+++ b/core/res/res/anim-sw720dp/task_open_enter.xml
@@ -23,20 +23,20 @@
<alpha android:fromAlpha="0" android:toAlpha="1.0"
android:fillEnabled="true" android:fillBefore="true" android:fillAfter="true"
android:interpolator="@interpolator/decelerate_quad"
- android:startOffset="300"
+ android:startOffset="500"
android:duration="400"/>
- <translate android:fromYDelta="120%" android:toYDelta="0"
+ <translate android:fromYDelta="50%" android:toYDelta="0"
android:fillEnabled="true" android:fillBefore="true" android:fillAfter="true"
android:interpolator="@interpolator/decelerate_quint"
- android:startOffset="300"
+ android:startOffset="500"
android:duration="400" />
- <scale android:fromXScale=".5" android:toXScale="1.0"
- android:fromYScale=".5" android:toYScale="1.0"
+ <scale android:fromXScale=".8" android:toXScale="1.0"
+ android:fromYScale=".8" android:toYScale="1.0"
android:pivotX="50%p" android:pivotY="100%p"
android:fillEnabled="true" android:fillBefore="true" android:fillAfter="true"
android:interpolator="@interpolator/decelerate_quad"
- android:startOffset="300"
+ android:startOffset="500"
android:duration="400" />
</set> \ No newline at end of file
diff --git a/core/res/res/anim-sw720dp/task_open_exit.xml b/core/res/res/anim-sw720dp/task_open_exit.xml
index 0ba35d7..dd25a0c 100644
--- a/core/res/res/anim-sw720dp/task_open_exit.xml
+++ b/core/res/res/anim-sw720dp/task_open_exit.xml
@@ -23,21 +23,21 @@
<alpha android:fromAlpha="1.0" android:toAlpha="0"
android:fillEnabled="true" android:fillBefore="true" android:fillAfter="true"
android:interpolator="@interpolator/accelerate_quad"
- android:duration="300"/>
+ android:duration="350"/>
- <translate android:fromYDelta="0" android:toYDelta="-120%"
+ <translate android:fromYDelta="0" android:toYDelta="-50%"
android:fillEnabled="true" android:fillBefore="true" android:fillAfter="true"
android:interpolator="@interpolator/accelerate_cubic"
- android:duration="300"/>
+ android:duration="350"/>
- <scale android:fromXScale="1.0" android:toXScale="0.5"
- android:fromYScale="1.0" android:toYScale="0.5"
+ <scale android:fromXScale="1.0" android:toXScale="0.8"
+ android:fromYScale="1.0" android:toYScale="0.8"
android:fillEnabled="true" android:fillBefore="true" android:fillAfter="true"
android:pivotX="50%p" android:pivotY="0%p"
android:interpolator="@interpolator/accelerate_quad"
- android:duration="300" />
+ android:duration="350" />
<!-- This is needed to keep the animation running while task_open_enter completes -->
<alpha android:fromAlpha="1.0" android:toAlpha="1.0"
- android:duration="700" />
+ android:duration="900" />
</set> \ No newline at end of file
diff --git a/core/res/res/anim/dock_bottom_enter.xml b/core/res/res/anim/dock_bottom_enter.xml
index 74a021b..4f2f753 100644
--- a/core/res/res/anim/dock_bottom_enter.xml
+++ b/core/res/res/anim/dock_bottom_enter.xml
@@ -18,7 +18,7 @@
<!-- Animation for when a dock window at the bottom of the screen is entering. -->
<set xmlns:android="http://schemas.android.com/apk/res/android"
- android:interpolator="@android:interpolator/decelerate_quad">
+ android:interpolator="@android:interpolator/decelerate_cubic">
<translate android:fromYDelta="100%" android:toYDelta="0"
- android:duration="@android:integer/config_mediumAnimTime"/>
+ android:duration="250"/>
</set>
diff --git a/core/res/res/anim/dock_bottom_exit.xml b/core/res/res/anim/dock_bottom_exit.xml
index 213b3d9..afbe24b 100644
--- a/core/res/res/anim/dock_bottom_exit.xml
+++ b/core/res/res/anim/dock_bottom_exit.xml
@@ -18,7 +18,7 @@
<!-- Animation for when a dock window at the bottom of the screen is exiting. -->
<set xmlns:android="http://schemas.android.com/apk/res/android"
- android:interpolator="@android:interpolator/accelerate_quad">
+ android:interpolator="@android:interpolator/accelerate_cubic">
<translate android:fromYDelta="0" android:toYDelta="100%"
- android:startOffset="100" android:duration="@android:integer/config_mediumAnimTime"/>
+ android:startOffset="100" android:duration="250"/>
</set>
diff --git a/core/res/res/anim/dock_left_enter.xml b/core/res/res/anim/dock_left_enter.xml
index 4fce35a..7f5dfd5 100644
--- a/core/res/res/anim/dock_left_enter.xml
+++ b/core/res/res/anim/dock_left_enter.xml
@@ -18,7 +18,7 @@
<!-- Animation for when a dock window at the left of the screen is entering. -->
<set xmlns:android="http://schemas.android.com/apk/res/android"
- android:interpolator="@android:interpolator/decelerate_quad">
+ android:interpolator="@android:interpolator/decelerate_cubic">
<translate android:fromXDelta="-100%" android:toXDelta="0"
- android:duration="@android:integer/config_mediumAnimTime"/>
+ android:duration="250"/>
</set>
diff --git a/core/res/res/anim/dock_left_exit.xml b/core/res/res/anim/dock_left_exit.xml
index bce203d..11cbc0b 100644
--- a/core/res/res/anim/dock_left_exit.xml
+++ b/core/res/res/anim/dock_left_exit.xml
@@ -18,7 +18,7 @@
<!-- Animation for when a dock window at the right of the screen is exiting. -->
<set xmlns:android="http://schemas.android.com/apk/res/android"
- android:interpolator="@android:interpolator/accelerate_quad">
+ android:interpolator="@android:interpolator/accelerate_cubic">
<translate android:fromXDelta="0" android:toXDelta="-100%"
- android:startOffset="100" android:duration="@android:integer/config_mediumAnimTime"/>
+ android:startOffset="100" android:duration="250"/>
</set>
diff --git a/core/res/res/anim/dock_right_enter.xml b/core/res/res/anim/dock_right_enter.xml
index 26b8ad6..a92c7d2 100644
--- a/core/res/res/anim/dock_right_enter.xml
+++ b/core/res/res/anim/dock_right_enter.xml
@@ -18,7 +18,7 @@
<!-- Animation for when a dock window at the right of the screen is entering. -->
<set xmlns:android="http://schemas.android.com/apk/res/android"
- android:interpolator="@android:interpolator/decelerate_quad">
+ android:interpolator="@android:interpolator/decelerate_cubic">
<translate android:fromXDelta="100%" android:toXDelta="0"
- android:duration="@android:integer/config_mediumAnimTime"/>
+ android:duration="250"/>
</set>
diff --git a/core/res/res/anim/dock_right_exit.xml b/core/res/res/anim/dock_right_exit.xml
index 6beda59..80e4dc3 100644
--- a/core/res/res/anim/dock_right_exit.xml
+++ b/core/res/res/anim/dock_right_exit.xml
@@ -18,7 +18,7 @@
<!-- Animation for when a dock window at the right of the screen is exiting. -->
<set xmlns:android="http://schemas.android.com/apk/res/android"
- android:interpolator="@android:interpolator/accelerate_quad">
+ android:interpolator="@android:interpolator/accelerate_cubic">
<translate android:fromXDelta="0" android:toXDelta="100%"
- android:startOffset="100" android:duration="@android:integer/config_mediumAnimTime"/>
+ android:startOffset="100" android:duration="250"/>
</set>
diff --git a/core/res/res/anim/dock_top_enter.xml b/core/res/res/anim/dock_top_enter.xml
index 594b479..1f74e48 100644
--- a/core/res/res/anim/dock_top_enter.xml
+++ b/core/res/res/anim/dock_top_enter.xml
@@ -18,7 +18,7 @@
<!-- Animation for when a dock window at the top of the screen is entering. -->
<set xmlns:android="http://schemas.android.com/apk/res/android"
- android:interpolator="@android:interpolator/decelerate_quad">
+ android:interpolator="@android:interpolator/decelerate_cubic">
<translate android:fromYDelta="-100%" android:toYDelta="0"
- android:duration="@android:integer/config_mediumAnimTime"/>
+ android:duration="250"/>
</set>
diff --git a/core/res/res/anim/dock_top_exit.xml b/core/res/res/anim/dock_top_exit.xml
index b9691f6..4d2fea9 100644
--- a/core/res/res/anim/dock_top_exit.xml
+++ b/core/res/res/anim/dock_top_exit.xml
@@ -18,7 +18,7 @@
<!-- Animation for when a dock window at the top of the screen is exiting. -->
<set xmlns:android="http://schemas.android.com/apk/res/android"
- android:interpolator="@android:interpolator/accelerate_quad">
+ android:interpolator="@android:interpolator/accelerate_cubic">
<translate android:fromYDelta="0" android:toYDelta="-100%"
- android:startOffset="100" android:duration="@android:integer/config_mediumAnimTime"/>
+ android:startOffset="100" android:duration="250"/>
</set>
diff --git a/core/res/res/layout/choose_selected_account_row.xml b/core/res/res/layout/choose_selected_account_row.xml
deleted file mode 100644
index d88750d..0000000
--- a/core/res/res/layout/choose_selected_account_row.xml
+++ /dev/null
@@ -1,46 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
--->
-
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:paddingLeft="0dip"
- android:paddingRight="0dip"
- android:orientation="horizontal" >
-
- <ImageView android:id="@+id/account_row_icon"
- android:layout_width="wrap_content"
- android:layout_height="fill_parent"
- android:paddingRight="8dip" />
-
- <TextView xmlns:android="http://schemas.android.com/apk/res/android"
- android:id="@+id/account_row_text"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:textAppearance="?android:attr/textAppearanceMedium"
- android:gravity="center_vertical"
- android:minHeight="?android:attr/listPreferredItemHeight" />
-
- <ImageView android:id="@+id/account_row_checkmark"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:gravity="right"
- android:layout_weight="2"
- android:paddingRight="8dip"
- android:src="@drawable/ic_checkmark_holo_light" />
-
-</LinearLayout> \ No newline at end of file
diff --git a/core/res/res/layout/choose_type_and_account.xml b/core/res/res/layout/choose_type_and_account.xml
index d7068b7..9d1d284 100644
--- a/core/res/res/layout/choose_type_and_account.xml
+++ b/core/res/res/layout/choose_type_and_account.xml
@@ -20,53 +20,52 @@
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
- android:orientation="vertical"
- android:paddingLeft="16dip"
- android:paddingRight="16dip">
-
- <TextView android:id="@+id/title"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:textAppearance="?android:attr/textAppearanceMedium"
- android:layout_gravity="left"
- android:text="@string/choose_account_label"
- android:paddingTop="16dip"
- android:paddingBottom="16dip"
- android:textColor="@android:color/holo_blue_light"
- />
-
- <View android:layout_height="3dip"
- android:layout_width="match_parent"
- android:background="#323232"/>
+ android:orientation="vertical">
+ <!-- Customizable description text -->
<TextView android:id="@+id/description"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
android:layout_gravity="left|center_vertical"
- android:text="@string/choose_account_text"
android:paddingTop="16dip"
android:paddingBottom="16dip"
+ android:paddingLeft="16dip"
+ android:paddingRight="16dip"
/>
+ <!-- List of accounts, with "Add new account" as the last item -->
<ListView android:id="@android:id/list"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:drawSelectorOnTop="false"
android:layout_weight="1"
- android:scrollbarAlwaysDrawVerticalTrack="true" />
+ android:scrollbarAlwaysDrawVerticalTrack="true"
+ android:choiceMode="singleChoice" />
+ <!-- Horizontal divider line -->
<View android:layout_height="1dip"
android:layout_width="match_parent"
android:background="?android:attr/dividerHorizontal" />
- <Button android:id="@+id/addAccount"
- style="?android:attr/buttonBarButtonStyle"
+ <!-- Alert dialog style buttons along the bottom. -->
+ <LinearLayout android:id="@+id/button_bar"
+ style="?android:attr/buttonBarStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:layout_marginLeft="2dip"
- android:layout_marginRight="2dip"
- android:textAppearance="?android:attr/textAppearanceMedium"
- android:text="@string/add_account_button_label"
- />
+ android:measureWithLargestChild="true">
+ <Button android:id="@android:id/button1"
+ style="?android:attr/buttonBarButtonStyle"
+ android:layout_width="wrap_content" android:layout_height="wrap_content"
+ android:layout_weight="1"
+ android:text="@android:string/no"
+ android:onClick="onCancelButtonClicked" />
+ <Button android:id="@android:id/button2"
+ style="?android:attr/buttonBarButtonStyle"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"
+ android:text="@android:string/yes"
+ android:onClick="onOkButtonClicked" />
+ </LinearLayout>
</LinearLayout>
diff --git a/core/res/res/layout/notification_action_list.xml b/core/res/res/layout/notification_action_list.xml
index fa0a8c8..591c9ea 100644
--- a/core/res/res/layout/notification_action_list.xml
+++ b/core/res/res/layout/notification_action_list.xml
@@ -23,6 +23,7 @@
android:visibility="gone"
android:showDividers="middle"
android:divider="?android:attr/listDivider"
+ android:dividerPadding="12dp"
>
<!-- actions will be added here -->
</LinearLayout>
diff --git a/core/res/res/layout/notification_template_base.xml b/core/res/res/layout/notification_template_base.xml
index ed680a9..47bbbde 100644
--- a/core/res/res/layout/notification_template_base.xml
+++ b/core/res/res/layout/notification_template_base.xml
@@ -36,8 +36,7 @@
android:layout_marginLeft="@dimen/notification_large_icon_width"
android:minHeight="@dimen/notification_large_icon_height"
android:orientation="vertical"
- android:paddingLeft="12dp"
- android:paddingRight="12dp"
+ android:paddingRight="8dp"
android:paddingTop="2dp"
android:paddingBottom="2dp"
android:gravity="top"
@@ -47,6 +46,7 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="6dp"
+ android:layout_marginLeft="8dp"
android:orientation="horizontal"
>
<TextView android:id="@+id/title"
@@ -81,6 +81,7 @@
android:layout_height="wrap_content"
android:layout_marginTop="-2dp"
android:layout_marginBottom="-2dp"
+ android:layout_marginLeft="8dp"
android:singleLine="true"
android:fadingEdge="horizontal"
android:ellipsize="marquee"
@@ -90,24 +91,17 @@
android:id="@android:id/progress"
android:layout_width="match_parent"
android:layout_height="12dp"
+ android:layout_marginLeft="8dp"
android:visibility="gone"
style="?android:attr/progressBarStyleHorizontal"
/>
- <TextView android:id="@+id/overflow_title"
- android:textAppearance="@style/TextAppearance.StatusBar.EventContent"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:singleLine="true"
- android:ellipsize="marquee"
- android:fadingEdge="horizontal"
- android:visibility="gone"
- android:layout_weight="1"
- />
<LinearLayout
android:id="@+id/line3"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
+ android:gravity="center_vertical"
+ android:layout_marginLeft="8dp"
>
<TextView android:id="@+id/text"
android:textAppearance="@style/TextAppearance.StatusBar.EventContent"
@@ -130,14 +124,14 @@
android:paddingLeft="8dp"
/>
<ImageView android:id="@+id/right_icon"
- android:layout_width="wrap_content"
- android:layout_height="match_parent"
+ android:layout_width="16dp"
+ android:layout_height="16dp"
android:layout_gravity="center"
android:layout_weight="0"
+ android:layout_marginLeft="8dp"
android:scaleType="centerInside"
- android:paddingLeft="8dp"
android:visibility="gone"
- android:drawableAlpha="180"
+ android:drawableAlpha="153"
/>
</LinearLayout>
</LinearLayout>
diff --git a/core/res/res/layout/notification_template_big_base.xml b/core/res/res/layout/notification_template_big_base.xml
index f2c204f..69f0a24 100644
--- a/core/res/res/layout/notification_template_big_base.xml
+++ b/core/res/res/layout/notification_template_big_base.xml
@@ -33,19 +33,16 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="fill_vertical"
- android:layout_marginLeft="@dimen/notification_large_icon_width"
android:minHeight="@dimen/notification_large_icon_height"
android:orientation="vertical"
- android:paddingLeft="12dp"
- android:paddingRight="12dp"
- android:paddingTop="2dp"
- android:paddingBottom="2dp"
android:gravity="top"
>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
+ android:layout_marginLeft="@dimen/notification_large_icon_width"
android:minHeight="@dimen/notification_large_icon_height"
+ android:paddingTop="2dp"
android:orientation="vertical"
>
<LinearLayout
@@ -53,6 +50,8 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="6dp"
+ android:layout_marginRight="8dp"
+ android:layout_marginLeft="8dp"
android:orientation="horizontal"
>
<TextView android:id="@+id/title"
@@ -87,6 +86,8 @@
android:layout_height="wrap_content"
android:layout_marginTop="-2dp"
android:layout_marginBottom="-2dp"
+ android:layout_marginLeft="8dp"
+ android:layout_marginRight="8dp"
android:singleLine="true"
android:fadingEdge="horizontal"
android:ellipsize="marquee"
@@ -96,6 +97,8 @@
android:textAppearance="@style/TextAppearance.StatusBar.EventContent"
android:layout_width="match_parent"
android:layout_height="wrap_content"
+ android:layout_marginLeft="8dp"
+ android:layout_marginRight="8dp"
android:singleLine="false"
android:visibility="gone"
/>
@@ -103,7 +106,10 @@
android:id="@+id/line3"
android:layout_width="match_parent"
android:layout_height="wrap_content"
+ android:layout_marginLeft="8dp"
+ android:layout_marginRight="8dp"
android:orientation="horizontal"
+ android:gravity="center_vertical"
>
<TextView android:id="@+id/text"
android:textAppearance="@style/TextAppearance.StatusBar.EventContent"
@@ -126,29 +132,38 @@
android:paddingLeft="8dp"
/>
<ImageView android:id="@+id/right_icon"
- android:layout_width="wrap_content"
- android:layout_height="match_parent"
+ android:layout_width="16dp"
+ android:layout_height="16dp"
android:layout_gravity="center"
android:layout_weight="0"
+ android:layout_marginLeft="8dp"
android:scaleType="centerInside"
- android:paddingLeft="8dp"
android:visibility="gone"
- android:drawableAlpha="180"
+ android:drawableAlpha="153"
/>
</LinearLayout>
<ProgressBar
android:id="@android:id/progress"
android:layout_width="match_parent"
android:layout_height="12dp"
+ android:layout_marginBottom="8dp"
+ android:layout_marginLeft="8dp"
+ android:layout_marginRight="8dp"
android:visibility="gone"
style="?android:attr/progressBarStyleHorizontal"
/>
</LinearLayout>
+ <ImageView
+ android:layout_width="match_parent"
+ android:layout_height="1px"
+ android:id="@+id/action_divider"
+ android:visibility="gone"
+ android:background="?android:attr/dividerHorizontal" />
<include
layout="@layout/notification_action_list"
- android:id="@+id/actions"
android:layout_width="match_parent"
android:layout_height="wrap_content"
+ android:layout_marginLeft="@dimen/notification_large_icon_width"
/>
</LinearLayout>
</FrameLayout>
diff --git a/core/res/res/layout/notification_template_big_picture.xml b/core/res/res/layout/notification_template_big_picture.xml
index 077616e..ecb3616 100644
--- a/core/res/res/layout/notification_template_big_picture.xml
+++ b/core/res/res/layout/notification_template_big_picture.xml
@@ -53,7 +53,6 @@
<include
layout="@layout/notification_action_list"
android:id="@+id/actions"
- android:layout_marginLeft="8dp"
android:layout_gravity="bottom"
android:layout_width="match_parent"
android:layout_height="wrap_content"
diff --git a/core/res/res/layout/notification_template_big_text.xml b/core/res/res/layout/notification_template_big_text.xml
index 304f2b5..b86177e 100644
--- a/core/res/res/layout/notification_template_big_text.xml
+++ b/core/res/res/layout/notification_template_big_text.xml
@@ -34,8 +34,6 @@
android:layout_gravity="fill_vertical"
android:layout_marginLeft="@dimen/notification_large_icon_width"
android:orientation="vertical"
- android:paddingLeft="12dp"
- android:paddingRight="12dp"
android:paddingTop="2dp"
android:paddingBottom="2dp"
android:gravity="top"
@@ -44,6 +42,8 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
+ android:layout_marginLeft="8dp"
+ android:layout_marginRight="8dp"
android:layout_weight="1"
>
<LinearLayout
@@ -87,6 +87,7 @@
android:layout_height="wrap_content"
android:layout_marginTop="-2dp"
android:layout_marginBottom="-2dp"
+ android:layout_marginRight="8dp"
android:singleLine="true"
android:fadingEdge="horizontal"
android:ellipsize="marquee"
@@ -97,6 +98,8 @@
android:id="@android:id/progress"
android:layout_width="match_parent"
android:layout_height="12dp"
+ android:layout_marginBottom="8dp"
+ android:layout_marginRight="8dp"
android:visibility="gone"
android:layout_weight="0"
style="?android:attr/progressBarStyleHorizontal"
@@ -105,7 +108,8 @@
android:textAppearance="@style/TextAppearance.StatusBar.EventContent"
android:layout_width="match_parent"
android:layout_height="0dp"
- android:layout_marginBottom="2dp"
+ android:layout_marginBottom="8dp"
+ android:layout_marginRight="8dp"
android:singleLine="false"
android:visibility="gone"
android:maxLines="8"
@@ -113,6 +117,13 @@
android:layout_weight="1"
/>
</LinearLayout>
+ <ImageView
+ android:layout_width="match_parent"
+ android:layout_height="1dip"
+ android:layout_marginTop="-1px"
+ android:id="@+id/action_divider"
+ android:visibility="gone"
+ android:background="?android:attr/dividerHorizontal" />
<include
layout="@layout/notification_action_list"
android:layout_width="match_parent"
@@ -120,22 +131,23 @@
android:visibility="gone"
android:layout_weight="1"
/>
- <TextView android:id="@+id/overflow_title"
- android:textAppearance="@style/TextAppearance.StatusBar.EventContent"
+ <ImageView
android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:singleLine="true"
- android:ellipsize="marquee"
- android:fadingEdge="horizontal"
- android:visibility="gone"
- android:layout_weight="0"
- />
+ android:layout_height="1px"
+ android:id="@+id/overflow_divider"
+ android:layout_marginBottom="8dp"
+ android:visibility="visible"
+ android:background="?android:attr/dividerHorizontal" />
<LinearLayout
android:id="@+id/line3"
android:layout_width="match_parent"
android:layout_height="wrap_content"
+ android:layout_marginLeft="8dp"
+ android:layout_marginBottom="8dp"
+ android:layout_marginRight="8dp"
android:orientation="horizontal"
android:layout_weight="0"
+ android:gravity="center_vertical"
>
<TextView android:id="@+id/text"
android:textAppearance="@style/TextAppearance.StatusBar.EventContent"
@@ -158,14 +170,14 @@
android:paddingLeft="8dp"
/>
<ImageView android:id="@+id/right_icon"
- android:layout_width="wrap_content"
- android:layout_height="match_parent"
+ android:layout_width="16dp"
+ android:layout_height="16dp"
android:layout_gravity="center"
android:layout_weight="0"
+ android:layout_marginLeft="8dp"
android:scaleType="centerInside"
- android:paddingLeft="8dp"
android:visibility="gone"
- android:drawableAlpha="180"
+ android:drawableAlpha="153"
/>
</LinearLayout>
</LinearLayout>
diff --git a/core/res/res/layout/notification_template_inbox.xml b/core/res/res/layout/notification_template_inbox.xml
index 121a81c..e9a3686 100644
--- a/core/res/res/layout/notification_template_inbox.xml
+++ b/core/res/res/layout/notification_template_inbox.xml
@@ -36,8 +36,6 @@
android:layout_marginLeft="@dimen/notification_large_icon_width"
android:minHeight="@dimen/notification_large_icon_height"
android:orientation="vertical"
- android:paddingLeft="12dp"
- android:paddingRight="12dp"
android:paddingTop="2dp"
android:paddingBottom="2dp"
android:gravity="top"
@@ -46,6 +44,8 @@
android:id="@+id/line1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
+ android:layout_marginLeft="8dp"
+ android:layout_marginRight="8dp"
android:paddingTop="6dp"
android:orientation="horizontal"
android:layout_weight="0"
@@ -82,6 +82,8 @@
android:layout_height="wrap_content"
android:layout_marginTop="-2dp"
android:layout_marginBottom="-2dp"
+ android:layout_marginLeft="8dp"
+ android:layout_marginRight="8dp"
android:singleLine="true"
android:fadingEdge="horizontal"
android:ellipsize="marquee"
@@ -92,6 +94,8 @@
android:id="@android:id/progress"
android:layout_width="match_parent"
android:layout_height="12dp"
+ android:layout_marginLeft="8dp"
+ android:layout_marginRight="8dp"
android:visibility="gone"
android:layout_weight="0"
style="?android:attr/progressBarStyleHorizontal"
@@ -100,6 +104,8 @@
android:textAppearance="@style/TextAppearance.StatusBar.EventContent"
android:layout_width="match_parent"
android:layout_height="0dp"
+ android:layout_marginLeft="8dp"
+ android:layout_marginRight="8dp"
android:singleLine="true"
android:ellipsize="end"
android:visibility="gone"
@@ -109,6 +115,8 @@
android:textAppearance="@style/TextAppearance.StatusBar.EventContent"
android:layout_width="match_parent"
android:layout_height="0dp"
+ android:layout_marginLeft="8dp"
+ android:layout_marginRight="8dp"
android:singleLine="true"
android:ellipsize="end"
android:visibility="gone"
@@ -118,6 +126,8 @@
android:textAppearance="@style/TextAppearance.StatusBar.EventContent"
android:layout_width="match_parent"
android:layout_height="0dp"
+ android:layout_marginLeft="8dp"
+ android:layout_marginRight="8dp"
android:singleLine="true"
android:ellipsize="end"
android:visibility="gone"
@@ -127,6 +137,8 @@
android:textAppearance="@style/TextAppearance.StatusBar.EventContent"
android:layout_width="match_parent"
android:layout_height="0dp"
+ android:layout_marginLeft="8dp"
+ android:layout_marginRight="8dp"
android:singleLine="true"
android:ellipsize="end"
android:visibility="gone"
@@ -136,6 +148,7 @@
android:textAppearance="@style/TextAppearance.StatusBar.EventContent"
android:layout_width="match_parent"
android:layout_height="0dp"
+ android:layout_marginLeft="8dp"
android:singleLine="true"
android:ellipsize="end"
android:visibility="gone"
@@ -145,6 +158,8 @@
android:textAppearance="@style/TextAppearance.StatusBar.EventContent"
android:layout_width="match_parent"
android:layout_height="0dp"
+ android:layout_marginLeft="8dp"
+ android:layout_marginRight="8dp"
android:singleLine="true"
android:ellipsize="end"
android:visibility="gone"
@@ -154,6 +169,8 @@
android:textAppearance="@style/TextAppearance.StatusBar.EventContent"
android:layout_width="match_parent"
android:layout_height="0dp"
+ android:layout_marginLeft="8dp"
+ android:layout_marginRight="8dp"
android:singleLine="true"
android:ellipsize="end"
android:visibility="gone"
@@ -163,35 +180,44 @@
android:textAppearance="@style/TextAppearance.StatusBar.EventContent"
android:layout_width="match_parent"
android:layout_height="0dp"
+ android:layout_marginLeft="8dp"
+ android:layout_marginRight="8dp"
android:singleLine="true"
android:ellipsize="end"
android:visibility="gone"
android:layout_weight="1"
android:text="@android:string/ellipsis"
/>
+ <ImageView
+ android:layout_width="match_parent"
+ android:layout_height="1px"
+ android:id="@+id/overflow_divider"
+ android:layout_marginTop="8dp"
+ android:visibility="visible"
+ android:background="?android:attr/dividerHorizontal" />
<include
layout="@layout/notification_action_list"
- android:id="@+id/actions"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="0"
/>
- <TextView android:id="@+id/overflow_title"
- android:textAppearance="@style/TextAppearance.StatusBar.EventContent"
+ <ImageView
android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:singleLine="true"
- android:ellipsize="marquee"
- android:fadingEdge="horizontal"
+ android:layout_height="1px"
+ android:id="@+id/action_divider"
android:visibility="gone"
- android:layout_weight="0"
- />
+ android:background="?android:attr/dividerHorizontal" /><!-- note: divider below actions -->
<LinearLayout
android:id="@+id/line3"
android:layout_width="match_parent"
android:layout_height="wrap_content"
+ android:layout_marginTop="8dp"
+ android:layout_marginLeft="8dp"
+ android:layout_marginBottom="8dp"
+ android:layout_marginRight="8dp"
android:orientation="horizontal"
android:layout_weight="0"
+ android:gravity="center_vertical"
>
<TextView android:id="@+id/text"
android:textAppearance="@style/TextAppearance.StatusBar.EventContent"
@@ -214,14 +240,14 @@
android:paddingLeft="8dp"
/>
<ImageView android:id="@+id/right_icon"
- android:layout_width="wrap_content"
- android:layout_height="match_parent"
+ android:layout_width="16dp"
+ android:layout_height="16dp"
android:layout_gravity="center"
android:layout_weight="0"
+ android:layout_marginLeft="8dp"
android:scaleType="centerInside"
- android:paddingLeft="8dp"
android:visibility="gone"
- android:drawableAlpha="180"
+ android:drawableAlpha="153"
/>
</LinearLayout>
</LinearLayout>
diff --git a/core/res/res/values-af/strings.xml b/core/res/res/values-af/strings.xml
index 732b0ab..fd32685 100644
--- a/core/res/res/values-af/strings.xml
+++ b/core/res/res/values-af/strings.xml
@@ -317,6 +317,8 @@
<string name="permdesc_readInputState" msgid="8387754901688728043">"Laat die program toe om te sien watter sleutels jy druk, selfs wanneer jy met \'n ander program besig is (soos om \'n wagwoord in te voer). Dit moet nooit vir normale programme nodig wees nie."</string>
<string name="permlab_bindInputMethod" msgid="3360064620230515776">"bind aan \'n invoermetode"</string>
<string name="permdesc_bindInputMethod" msgid="3250440322807286331">"Dit laat die houer toe om aan die topvlak-koppelvlak van \'n invoermetode te bind. Dit moet nooit vir normale programme nodig wees nie."</string>
+ <string name="permlab_bindAccessibilityService" msgid="5357733942556031593">"verbind aan \'n toeganklikheidsdiens"</string>
+ <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Dit laat die houer toe om aan die top-koppelvlak van \'n toeganklikheidsdiens te verbind. Behoort nooit vir gewone programme nodig te wees nie."</string>
<string name="permlab_bindTextService" msgid="7358378401915287938">"bind aan \'n teksdiens"</string>
<string name="permdesc_bindTextService" msgid="8151968910973998670">"Dit laat die houer toe om aan die topvlak-koppelvlak van \'n teksdiens (bv SpellCheckerService) te bind. Dit moet nooit vir normale programme nodig wees nie."</string>
<string name="permlab_bindVpnService" msgid="4708596021161473255">"bind aan \'n VPN-diens"</string>
@@ -853,6 +855,12 @@
<string name="searchview_description_clear" msgid="1330281990951833033">"Maak navraag skoon"</string>
<string name="searchview_description_submit" msgid="2688450133297983542">"Dien navraag in"</string>
<string name="searchview_description_voice" msgid="2453203695674994440">"Stemsoektog"</string>
+ <!-- no translation found for enable_explore_by_touch_warning_title (7460694070309730149) -->
+ <skip />
+ <!-- no translation found for enable_explore_by_touch_warning_message (8655887539089910577) -->
+ <skip />
+ <!-- no translation found for enable_explore_by_touch_warning_message (2708199672852373195) -->
+ <skip />
<string name="oneMonthDurationPast" msgid="7396384508953779925">"1 maand gelede"</string>
<string name="beforeOneMonthDurationPast" msgid="909134546836499826">"Voor 1 maand gelede"</string>
<plurals name="num_seconds_ago">
@@ -1119,6 +1127,10 @@
<string name="configure_input_methods" msgid="9091652157722495116">"Stel invoermetodes op"</string>
<string name="use_physical_keyboard" msgid="6203112478095117625">"Fisiese sleutelbord"</string>
<string name="hardware" msgid="7517821086888990278">"Hardeware"</string>
+ <!-- no translation found for select_keyboard_layout_notification_title (1407367017263030773) -->
+ <skip />
+ <!-- no translation found for select_keyboard_layout_notification_message (4465907700449257063) -->
+ <skip />
<string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="candidates_style" msgid="4333913089637062257"><u>"kandidate"</u></string>
@@ -1312,5 +1324,6 @@
<string name="launchBrowserDefault" msgid="2057951947297614725">"Begin webblaaier?"</string>
<string name="SetupCallDefault" msgid="5834948469253758575">"Aanvaar oproep?"</string>
<string name="activity_resolver_use_always" msgid="8017770747801494933">"Altyd"</string>
- <string name="activity_resolver_use_once" msgid="405646673463328329">"Net een keer"</string>
+ <!-- no translation found for activity_resolver_use_once (2404644797149173758) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml
index 6f17bec..fb11af3 100644
--- a/core/res/res/values-am/strings.xml
+++ b/core/res/res/values-am/strings.xml
@@ -317,6 +317,8 @@
<string name="permdesc_readInputState" msgid="8387754901688728043">"ከሌላ መተግበሪያ( ልክ እንደ የይለፍ ቃል መጫን) ጋር በምትገናኝበት ጊዜ እንኳን የተጫንካቸውን ቁልፎች ለማየት ለመተግበሪያው ይፈቅዳሉ፡፡ ለመደበኛ መተግበሪያዎች መቼም ቢሆን አያስፈልግም፡፡"</string>
<string name="permlab_bindInputMethod" msgid="3360064620230515776">"በግቤት ሜተድ ጠርዝ"</string>
<string name="permdesc_bindInputMethod" msgid="3250440322807286331">"ያዡ ግቤት ስልቱን ወደ ከፍተኛ-ደረጃ በይነገጽ ለመጠረዝ ይፈቅዳሉ። ለመደበኛ ትግበራዎች በፍፁም አያስፈልግም።"</string>
+ <string name="permlab_bindAccessibilityService" msgid="5357733942556031593">"ከአንድ የተደራሽነት አገልግሎት ጋር እሰር"</string>
+ <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"ያዢው ወደ የአንድ ተደራሽነት አገልግሎት ከፍተኛ-ደረጃ በይነገጽ እንዲያስር ይፈቅድለታል። ለመደበኛ መተግበሪያዎች መቼም ቢሆን ሊያስፈልግ አይገባም።"</string>
<string name="permlab_bindTextService" msgid="7358378401915287938">"ለፅሁፍ አገልግሎት አሰረ"</string>
<string name="permdesc_bindTextService" msgid="8151968910973998670">"ያዡ ግቤት ለከፍተኛ-ደረጃ የፅሁፍ አገልግሎት ገፅታ ለመጠረዝ ይፈቅዳል። ለመደበኛ ትግበራዎች በፍፁም አያስፈልግም።"</string>
<string name="permlab_bindVpnService" msgid="4708596021161473255">"ለVPN አገልግሎት ተገዛ"</string>
@@ -853,6 +855,9 @@
<string name="searchview_description_clear" msgid="1330281990951833033">"ጥያቄ አጥራ"</string>
<string name="searchview_description_submit" msgid="2688450133297983542">"ጥያቄ አስረክብ"</string>
<string name="searchview_description_voice" msgid="2453203695674994440">"የድምፅ ፍለጋ"</string>
+ <string name="enable_explore_by_touch_warning_title" msgid="7460694070309730149">"በመንካት አስስ ይንቃ?"</string>
+ <string name="enable_explore_by_touch_warning_message" product="tablet" msgid="8655887539089910577">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> ማሰስን በንኪ ማንቃት ይፈልጋል። አስስ በንኪ በሚበራበት ጊዜ፣ ከጡባዊ ተኮው ጋር ለመግባባት ምን በጣትህ ስር ወይም ምልክቶችን ማከናወን እንዳለብህ ማብራሪያ ልታይ ወይም ልትሰማ ትችላለህ።"</string>
+ <string name="enable_explore_by_touch_warning_message" product="default" msgid="2708199672852373195">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> ማሰስን በንኪ ማንቃት ይፈልጋል። አስስ በንኪ በሚበራበት ጊዜ፣ ከስልኩ ጋር ለመግባባት ምን በጣትህ ስር ወይም ምልክቶችን ማከናወን እንዳለብህ ማብራሪያ ልታይ ወይም ልትሰማ ትችላለህ።"</string>
<string name="oneMonthDurationPast" msgid="7396384508953779925">"ከ1 ወር በፊት"</string>
<string name="beforeOneMonthDurationPast" msgid="909134546836499826">"ከ1 ወር በፊት"</string>
<plurals name="num_seconds_ago">
@@ -1119,6 +1124,8 @@
<string name="configure_input_methods" msgid="9091652157722495116">"የግቤት ስልቶችን አዘጋጅ"</string>
<string name="use_physical_keyboard" msgid="6203112478095117625">"የሚዳሰስ የቁልፍ ሰሌዳ"</string>
<string name="hardware" msgid="7517821086888990278">"ሃርድዌር"</string>
+ <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"የቁልፍ ሰሌዳ አቀማመጥ ምረጥ"</string>
+ <string name="select_keyboard_layout_notification_message" msgid="4465907700449257063">"የቁልፍ ሰሌዳ አቀማመጥ ለመምረጥ ንካ።"</string>
<string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="candidates_style" msgid="4333913089637062257"><u>"ዕጩዎች"</u></string>
@@ -1312,5 +1319,5 @@
<string name="launchBrowserDefault" msgid="2057951947297614725">"ማሰሺያን አስነሳ?"</string>
<string name="SetupCallDefault" msgid="5834948469253758575">"ጥሪ ተቀበል?"</string>
<string name="activity_resolver_use_always" msgid="8017770747801494933">"ዘወትር"</string>
- <string name="activity_resolver_use_once" msgid="405646673463328329">"አንዴ ብቻ"</string>
+ <string name="activity_resolver_use_once" msgid="2404644797149173758">"አንዴ ብቻ"</string>
</resources>
diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml
index dca63c3..d70aec8 100644
--- a/core/res/res/values-ar/strings.xml
+++ b/core/res/res/values-ar/strings.xml
@@ -317,6 +317,8 @@
<string name="permdesc_readInputState" msgid="8387754901688728043">"للسماح للتطبيقات بمراقبة الأحرف التي تضغط عليها حتى عند التفاعل مع تطبيق آخر (مثل إدخال كلمة مرور). لن تكون هناك حاجة إليه مطلقًا مع التطبيقات العادية."</string>
<string name="permlab_bindInputMethod" msgid="3360064620230515776">"الالتزام بطريقة إرسال ما"</string>
<string name="permdesc_bindInputMethod" msgid="3250440322807286331">"للسماح للمالك بالالتزام بواجهة المستوى العلوي لأسلوب الإدخال. لن تكون هناك حاجة إليه مطلقًا مع التطبيقات العادية."</string>
+ <string name="permlab_bindAccessibilityService" msgid="5357733942556031593">"الالتزام بخدمة إمكانية الدخول"</string>
+ <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"للسماح للمالك بالالتزام بواجهة المستوى العلوي لخدمة إمكانية الدخول. لن تكون هناك حاجة إليه مطلقًا مع التطبيقات العادية."</string>
<string name="permlab_bindTextService" msgid="7358378401915287938">"الالتزام بخدمة إدخال النصوص"</string>
<string name="permdesc_bindTextService" msgid="8151968910973998670">"للسماح للمالك بالالتزام بواجهة المستوى العلوي لخدمة إدخال النصوص (على سبيل المثال، SpellCheckerService). لن تكون هناك حاجة إليه مطلقًا مع التطبيقات العادية."</string>
<string name="permlab_bindVpnService" msgid="4708596021161473255">"الالتزام بخدمة VPN"</string>
@@ -853,6 +855,9 @@
<string name="searchview_description_clear" msgid="1330281990951833033">"محو طلب البحث"</string>
<string name="searchview_description_submit" msgid="2688450133297983542">"إرسال طلب البحث"</string>
<string name="searchview_description_voice" msgid="2453203695674994440">"البحث الصوتي"</string>
+ <string name="enable_explore_by_touch_warning_title" msgid="7460694070309730149">"هل تريد تمكين ميزة Explore by Touch؟"</string>
+ <string name="enable_explore_by_touch_warning_message" product="tablet" msgid="8655887539089910577">"يريد <xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> تمكين ميزة Explore by Touch. عند تشغيل ميزة Explore by Touch، سيكون بإمكانك سماع أو مشاهدة أوصاف لما تحت إصبعك أو إجراء إيماءات للتفاعل مع الجهاز اللوحي."</string>
+ <string name="enable_explore_by_touch_warning_message" product="default" msgid="2708199672852373195">"يريد <xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> تمكين ميزة Explore by Touch. عند تشغيل ميزة Explore by Touch، سيكون بإمكانك سماع أو مشاهدة أوصاف لما تحت إصبعك أو إجراء إيماءات للتفاعل مع الهاتف."</string>
<string name="oneMonthDurationPast" msgid="7396384508953779925">"قبل شهر واحد"</string>
<string name="beforeOneMonthDurationPast" msgid="909134546836499826">"قبل شهر واحد"</string>
<plurals name="num_seconds_ago">
@@ -1119,6 +1124,8 @@
<string name="configure_input_methods" msgid="9091652157722495116">"إعداد أسلوب الإدخال"</string>
<string name="use_physical_keyboard" msgid="6203112478095117625">"لوحة مفاتيح فعلية"</string>
<string name="hardware" msgid="7517821086888990278">"أجهزة"</string>
+ <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"تحديد تخطيط لوحة مفاتيح"</string>
+ <string name="select_keyboard_layout_notification_message" msgid="4465907700449257063">"المس لتحديد تخطيط لوحة مفاتيح."</string>
<string name="fast_scroll_alphabet" msgid="5433275485499039199">" أ ب ت ث ج ح خ د ذ ر ز س ش ص ض ط ظ ع غ ف ق ك ل م ن ه و ي"</string>
<string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789 أ ب ت ث ج ح خ د ذ ر ز س ش ص ض ط ظ ع غ ف ق ك ل م ن ه و ي"</string>
<string name="candidates_style" msgid="4333913089637062257"><u>"العناصر المرشحة"</u></string>
@@ -1312,5 +1319,5 @@
<string name="launchBrowserDefault" msgid="2057951947297614725">"تشغيل المتصفح؟"</string>
<string name="SetupCallDefault" msgid="5834948469253758575">"هل تريد قبول المكالمة؟"</string>
<string name="activity_resolver_use_always" msgid="8017770747801494933">"دومًا"</string>
- <string name="activity_resolver_use_once" msgid="405646673463328329">"مرة واحدة فقط"</string>
+ <string name="activity_resolver_use_once" msgid="2404644797149173758">"مرة واحدة فقط"</string>
</resources>
diff --git a/core/res/res/values-be/strings.xml b/core/res/res/values-be/strings.xml
index a95541e..4068610 100644
--- a/core/res/res/values-be/strings.xml
+++ b/core/res/res/values-be/strings.xml
@@ -317,6 +317,8 @@
<string name="permdesc_readInputState" msgid="8387754901688728043">"Дазваляе прыкладанням адсочваць клавішы, якія вы націскаеце, нават падчас узаемадзеяння з іншым прыкладаннем (напрыклад, пры ўводзе пароля). Не патрабуецца для звычайных прыкладанняў."</string>
<string name="permlab_bindInputMethod" msgid="3360064620230515776">"звязацца з метадам уводу"</string>
<string name="permdesc_bindInputMethod" msgid="3250440322807286331">"Дазваляе ўладальніку прывязвацца да інтэрфейсу верхняга ўзроўню метада ўводу. Не патрабуецца для звычайных прыкладанняў."</string>
+ <string name="permlab_bindAccessibilityService" msgid="5357733942556031593">"прывязацца да службы доступу"</string>
+ <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Дазваляе ўладальніку прывязвацца да інтэрфейсу верхняга ўзроўню службы доступу. Не патрабуецца для звычайных прыкладанняў."</string>
<string name="permlab_bindTextService" msgid="7358378401915287938">"звязаць з тэкставай службай"</string>
<string name="permdesc_bindTextService" msgid="8151968910973998670">"Дазваляе ўладальніку прывязвацца да інтэрфейсу верхняга ўзроўню тэкставай паслугі (напрыклад, SpellCheckerService). Ніколі не патрабуецца для звычайных прыкладанняў."</string>
<string name="permlab_bindVpnService" msgid="4708596021161473255">"звязвацца з VPN сэрвісам"</string>
@@ -853,6 +855,12 @@
<string name="searchview_description_clear" msgid="1330281990951833033">"Выдаліць запыт"</string>
<string name="searchview_description_submit" msgid="2688450133297983542">"Адправіць запыт"</string>
<string name="searchview_description_voice" msgid="2453203695674994440">"Галасавы пошук"</string>
+ <!-- no translation found for enable_explore_by_touch_warning_title (7460694070309730149) -->
+ <skip />
+ <!-- no translation found for enable_explore_by_touch_warning_message (8655887539089910577) -->
+ <skip />
+ <!-- no translation found for enable_explore_by_touch_warning_message (2708199672852373195) -->
+ <skip />
<string name="oneMonthDurationPast" msgid="7396384508953779925">"1 месяц таму"</string>
<string name="beforeOneMonthDurationPast" msgid="909134546836499826">"Раней, чым 1 месяц таму"</string>
<plurals name="num_seconds_ago">
@@ -1119,6 +1127,10 @@
<string name="configure_input_methods" msgid="9091652157722495116">"Наладзіць метады ўводу"</string>
<string name="use_physical_keyboard" msgid="6203112478095117625">"Фізічная клавіятура"</string>
<string name="hardware" msgid="7517821086888990278">"Апар. ср."</string>
+ <!-- no translation found for select_keyboard_layout_notification_title (1407367017263030773) -->
+ <skip />
+ <!-- no translation found for select_keyboard_layout_notification_message (4465907700449257063) -->
+ <skip />
<string name="fast_scroll_alphabet" msgid="5433275485499039199">" АБВГДЕЁЖЗІЙКЛМНОПРСТУЎФХЦЧШ\'ЫЬЭЮЯ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="candidates_style" msgid="4333913089637062257"><u>"кандыдат."</u></string>
@@ -1312,5 +1324,6 @@
<string name="launchBrowserDefault" msgid="2057951947297614725">"Запусцiць браўзер?"</string>
<string name="SetupCallDefault" msgid="5834948469253758575">"Прыняць выклік?"</string>
<string name="activity_resolver_use_always" msgid="8017770747801494933">"Заўсёды"</string>
- <string name="activity_resolver_use_once" msgid="405646673463328329">"Толькі адзін раз"</string>
+ <!-- no translation found for activity_resolver_use_once (2404644797149173758) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml
index 6ebe576..086d33a 100644
--- a/core/res/res/values-bg/strings.xml
+++ b/core/res/res/values-bg/strings.xml
@@ -317,6 +317,8 @@
<string name="permdesc_readInputState" msgid="8387754901688728043">"Разрешава на приложенията да наблюдават кои клавиши натискате дори и когато взаимодействате с друго приложение (например когато въвеждате парола). Нормалните приложения би трябвало никога да не се нуждаят от това."</string>
<string name="permlab_bindInputMethod" msgid="3360064620230515776">"обвързване с метод на въвеждане"</string>
<string name="permdesc_bindInputMethod" msgid="3250440322807286331">"Разрешава на притежателя да се обвърже с интерфейса от най-високото ниво на метод на въвеждане. Нормалните приложения би трябвало никога да не се нуждаят от това."</string>
+ <string name="permlab_bindAccessibilityService" msgid="5357733942556031593">"обвързване с услуга за достъпност"</string>
+ <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Разрешава на притежателя да се обвърже с интерфейса от най-високото ниво на услуга за достъпност. Нормалните приложения би трябвало никога да не се нуждаят от това."</string>
<string name="permlab_bindTextService" msgid="7358378401915287938">"обвързване с текстова услуга"</string>
<string name="permdesc_bindTextService" msgid="8151968910973998670">"Разрешава на притежателя да се обвърже с интерфейса от най-високото ниво на текстова услуга (напр. SpellCheckerService). Нормалните приложения би трябвало никога да не се нуждаят от това."</string>
<string name="permlab_bindVpnService" msgid="4708596021161473255">"обвързване с услуга за VPN"</string>
@@ -853,6 +855,12 @@
<string name="searchview_description_clear" msgid="1330281990951833033">"Изчистване на заявката"</string>
<string name="searchview_description_submit" msgid="2688450133297983542">"Изпращане на заявката"</string>
<string name="searchview_description_voice" msgid="2453203695674994440">"Гласово търсене"</string>
+ <!-- no translation found for enable_explore_by_touch_warning_title (7460694070309730149) -->
+ <skip />
+ <!-- no translation found for enable_explore_by_touch_warning_message (8655887539089910577) -->
+ <skip />
+ <!-- no translation found for enable_explore_by_touch_warning_message (2708199672852373195) -->
+ <skip />
<string name="oneMonthDurationPast" msgid="7396384508953779925">"Преди 1 месец"</string>
<string name="beforeOneMonthDurationPast" msgid="909134546836499826">"Преди повече от месец"</string>
<plurals name="num_seconds_ago">
@@ -1119,6 +1127,10 @@
<string name="configure_input_methods" msgid="9091652157722495116">"Методи на въвеждане: Настройка"</string>
<string name="use_physical_keyboard" msgid="6203112478095117625">"Физическа клавиатура"</string>
<string name="hardware" msgid="7517821086888990278">"Хардуер"</string>
+ <!-- no translation found for select_keyboard_layout_notification_title (1407367017263030773) -->
+ <skip />
+ <!-- no translation found for select_keyboard_layout_notification_message (4465907700449257063) -->
+ <skip />
<string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="candidates_style" msgid="4333913089637062257"><u>"кандидати"</u></string>
@@ -1312,5 +1324,6 @@
<string name="launchBrowserDefault" msgid="2057951947297614725">"Да се стартира ли браузърът?"</string>
<string name="SetupCallDefault" msgid="5834948469253758575">"Да се приеме ли обаждането?"</string>
<string name="activity_resolver_use_always" msgid="8017770747801494933">"Винаги"</string>
- <string name="activity_resolver_use_once" msgid="405646673463328329">"Само веднъж"</string>
+ <!-- no translation found for activity_resolver_use_once (2404644797149173758) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml
index 5766f15..4190bdb 100644
--- a/core/res/res/values-ca/strings.xml
+++ b/core/res/res/values-ca/strings.xml
@@ -317,6 +317,8 @@
<string name="permdesc_readInputState" msgid="8387754901688728043">"Permet que les aplicacions facin un seguiment de les tecles que prems, fins i tot quan s\'interactua amb una altra aplicació (com ara introduir una contrasenya). No s\'hauria de necessitar mai per a les aplicacions normals."</string>
<string name="permlab_bindInputMethod" msgid="3360064620230515776">"vincular a un mètode d\'entrada"</string>
<string name="permdesc_bindInputMethod" msgid="3250440322807286331">"Permet que el titular vinculi a la interfície de nivell superior d\'un mètode d\'entrada. No s\'hauria de necessitar mai per a les aplicacions normals."</string>
+ <string name="permlab_bindAccessibilityService" msgid="5357733942556031593">"vincular amb un servei d\'accessibilitat"</string>
+ <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Permet vincular amb la interfície de nivell superior d\'un servei d\'accessibilitat. Les aplicacions normals no haurien de necessitar-ho."</string>
<string name="permlab_bindTextService" msgid="7358378401915287938">"vincula a un servei de text"</string>
<string name="permdesc_bindTextService" msgid="8151968910973998670">"Permet al titular vincular amb la interfície de nivell superior d\'un servei de text (per exemple, SpellCheckerService). Les aplicacions normals mai no ho haurien de necessitar."</string>
<string name="permlab_bindVpnService" msgid="4708596021161473255">"vincula a un servei de VPN"</string>
@@ -529,15 +531,15 @@
<string name="permlab_changeWifiMulticastState" msgid="1368253871483254784">"permetre la recepció de multidifusió Wi-fi"</string>
<string name="permdesc_changeWifiMulticastState" msgid="7633598524564320817">"Permet que l\'aplicació rebi paquets que no estiguin adreçats directament al teu dispositiu. Pot ser útil en detectar els serveis que s\'ofereixen a prop. Consumeix més energia que el mode que no utilitza la multidestinació."</string>
<string name="permlab_bluetoothAdmin" msgid="6006967373935926659">"accés a la configuració de Bluetooth"</string>
- <string name="permdesc_bluetoothAdmin" product="tablet" msgid="6921177471748882137">"Permet que l\'aplicació configuri la tauleta Bluetooth local i que cerqui i emparelli dispositius remots."</string>
- <string name="permdesc_bluetoothAdmin" product="default" msgid="8931682159331542137">"Permet que l\'aplicació configuri el telèfon Bluetooth local i que cerqui i emparelli dispositius remots."</string>
+ <string name="permdesc_bluetoothAdmin" product="tablet" msgid="6921177471748882137">"Permet que l\'aplicació configuri la tauleta Bluetooth local i que cerqui i sincronitzi dispositius remots."</string>
+ <string name="permdesc_bluetoothAdmin" product="default" msgid="8931682159331542137">"Permet que l\'aplicació configuri el telèfon Bluetooth local i que cerqui i sincronitzi dispositius remots."</string>
<string name="permlab_accessWimaxState" msgid="7436749103151096452">"Visualització de les connexions WiMAX"</string>
<string name="permdesc_accessWimaxState" msgid="5914958077555177749">"Permet que l\'aplicació visualitzi la informació sobre l\'estat de WiMAX."</string>
<string name="permlab_changeWimaxState" msgid="2405042267131496579">"Canvia l\'estat de WiMAX"</string>
<string name="permdesc_changeWimaxState" msgid="3328853825006455912">"Permet que l\'aplicació es connecti i es desconnecti de la xarxa WiMAX."</string>
<string name="permlab_bluetooth" msgid="6127769336339276828">"sincronització amb dispositius Bluetooth"</string>
- <string name="permdesc_bluetooth" product="tablet" msgid="7007851048416363446">"Permet que l\'aplicació mostri la configuració de la tauleta Bluetooth local i que estableixi i accepti connexions amb dispositius emparellats."</string>
- <string name="permdesc_bluetooth" product="default" msgid="31846362767164948">"Permet que una aplicació visualitzi la configuració del telèfon Bluetooth local i que estableixi i accepti connexions amb els dispositius emparellats."</string>
+ <string name="permdesc_bluetooth" product="tablet" msgid="7007851048416363446">"Permet que l\'aplicació mostri la configuració de la tauleta Bluetooth local i que estableixi i accepti connexions amb dispositius sincronitzats."</string>
+ <string name="permdesc_bluetooth" product="default" msgid="31846362767164948">"Permet que una aplicació visualitzi la configuració del telèfon Bluetooth local i que estableixi i accepti connexions amb els dispositius sincronitzats."</string>
<string name="permlab_nfc" msgid="4423351274757876953">"controla Near Field Communication (NFC)"</string>
<string name="permdesc_nfc" msgid="7120611819401789907">"Permet que l\'aplicació es comuniqui amb les etiquetes, les targetes i els lectors de Near Field Communication (NFC)."</string>
<string name="permlab_disableKeyguard" msgid="3598496301486439258">"desactivació del bloqueig de pantalla"</string>
@@ -853,6 +855,9 @@
<string name="searchview_description_clear" msgid="1330281990951833033">"Neteja la consulta"</string>
<string name="searchview_description_submit" msgid="2688450133297983542">"Envia la consulta"</string>
<string name="searchview_description_voice" msgid="2453203695674994440">"Cerca per veu"</string>
+ <string name="enable_explore_by_touch_warning_title" msgid="7460694070309730149">"Vols activar l\'Exploració per tacte?"</string>
+ <string name="enable_explore_by_touch_warning_message" product="tablet" msgid="8655887539089910577">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> vol activar l\'Exploració per tacte. Quan l\'Exploració per tacte està activada, pots escoltar o veure les descripcions del que hi ha sota el dit o fer gestos per interactuar amb la tauleta."</string>
+ <string name="enable_explore_by_touch_warning_message" product="default" msgid="2708199672852373195">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> vol activar l\'Exploració per tacte. Quan l\'Exploració per tacte està activada, pots escoltar o veure les descripcions del que hi ha sota el dit o fer gestos per interactuar amb el telèfon."</string>
<string name="oneMonthDurationPast" msgid="7396384508953779925">"Fa 1 mes"</string>
<string name="beforeOneMonthDurationPast" msgid="909134546836499826">"Fa menys d\'1 mes"</string>
<plurals name="num_seconds_ago">
@@ -1119,6 +1124,8 @@
<string name="configure_input_methods" msgid="9091652157722495116">"Configura els mètodes d\'entrada"</string>
<string name="use_physical_keyboard" msgid="6203112478095117625">"Teclat físic"</string>
<string name="hardware" msgid="7517821086888990278">"Maquinari"</string>
+ <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"Selecciona una disposició de teclat"</string>
+ <string name="select_keyboard_layout_notification_message" msgid="4465907700449257063">"Toca per seleccionar una disposició de teclat."</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>"candidats"</u></string>
@@ -1312,5 +1319,5 @@
<string name="launchBrowserDefault" msgid="2057951947297614725">"Vols iniciar el navegador?"</string>
<string name="SetupCallDefault" msgid="5834948469253758575">"Vols acceptar la trucada?"</string>
<string name="activity_resolver_use_always" msgid="8017770747801494933">"Sempre"</string>
- <string name="activity_resolver_use_once" msgid="405646673463328329">"Només una vegada"</string>
+ <string name="activity_resolver_use_once" msgid="2404644797149173758">"Només una"</string>
</resources>
diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml
index fb8f466..ad25a3e 100644
--- a/core/res/res/values-cs/strings.xml
+++ b/core/res/res/values-cs/strings.xml
@@ -125,7 +125,7 @@
<string name="httpErrorFile" msgid="2170788515052558676">"Do souboru nelze získat přístup."</string>
<string name="httpErrorFileNotFound" msgid="6203856612042655084">"Požadovaný soubor nelze najít."</string>
<string name="httpErrorTooManyRequests" msgid="1235396927087188253">"Je zpracováváno příliš mnoho požadavků. Opakujte akci později."</string>
- <string name="notification_title" msgid="8967710025036163822">"Chyba přihlášení do účtu <xliff:g id="ACCOUNT">%1$s</xliff:g>"</string>
+ <string name="notification_title" msgid="8967710025036163822">"Chyba přihlášení k účtu <xliff:g id="ACCOUNT">%1$s</xliff:g>"</string>
<string name="contentServiceSync" msgid="8353523060269335667">"Synchronizace"</string>
<string name="contentServiceSyncNotificationTitle" msgid="397743349191901458">"Synchronizace"</string>
<string name="contentServiceTooManyDeletesNotificationDesc" msgid="8100981435080696431">"Příliš mnoho smazaných položek služby <xliff:g id="CONTENT_TYPE">%s</xliff:g>."</string>
@@ -145,7 +145,7 @@
<string name="shutdown_progress" msgid="2281079257329981203">"Vypínání..."</string>
<string name="shutdown_confirm" product="tablet" msgid="3385745179555731470">"Tablet se vypne."</string>
<string name="shutdown_confirm" product="default" msgid="649792175242821353">"Váš telefon bude vypnut."</string>
- <string name="shutdown_confirm_question" msgid="2906544768881136183">"Chcete vypnout telefon?"</string>
+ <string name="shutdown_confirm_question" msgid="2906544768881136183">"Chcete zařízení vypnout?"</string>
<string name="reboot_safemode_title" msgid="7054509914500140361">"Restart v nouzovém režimu"</string>
<string name="reboot_safemode_confirm" msgid="55293944502784668">"Chcete zařízení restartovat v nouzovém režimu? Deaktivujete tak veškeré nainstalované aplikace třetích stran. Po dalším restartu budou obnoveny."</string>
<string name="recent_tasks_title" msgid="3691764623638127888">"Nejnovější"</string>
@@ -317,6 +317,8 @@
<string name="permdesc_readInputState" msgid="8387754901688728043">"Umožňuje aplikaci sledovat, které klávesy stisknete, a to i při interakci s jinou aplikací (např. zadávání hesla). Běžné aplikace by toto oprávnění neměly nikdy požadovat."</string>
<string name="permlab_bindInputMethod" msgid="3360064620230515776">"vazba k metodě zadávání dat"</string>
<string name="permdesc_bindInputMethod" msgid="3250440322807286331">"Umožňuje držiteli vázat se na nejvyšší úroveň rozhraní pro zadávání dat. Běžné aplikace by toto oprávnění neměly nikdy požadovat."</string>
+ <string name="permlab_bindAccessibilityService" msgid="5357733942556031593">"navázat se na službu usnadnění přístupu"</string>
+ <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Umožňuje držiteli navázat se na nejvyšší úroveň rozhraní služby usnadnění přístupu. Běžné aplikace by toto oprávnění neměly nikdy požadovat."</string>
<string name="permlab_bindTextService" msgid="7358378401915287938">"navázat se na textovou službu"</string>
<string name="permdesc_bindTextService" msgid="8151968910973998670">"Umožňuje držiteli připojit se k nejvyšší úrovni rozhraní textové služby (např. SpellCheckerService). Běžné aplikace by toto oprávnění neměly nikdy požadovat."</string>
<string name="permlab_bindVpnService" msgid="4708596021161473255">"navázat se na službu VPN"</string>
@@ -730,7 +732,7 @@
<string name="lockscreen_pattern_wrong" msgid="4317955014948108794">"Zkusit znovu"</string>
<string name="lockscreen_password_wrong" msgid="5737815393253165301">"Zkusit znovu"</string>
<string name="faceunlock_multiple_failures" msgid="754137583022792429">"Překročili jste maximální povolený počet pokusů o odemknutí obličejem."</string>
- <string name="lockscreen_plugged_in" msgid="8057762828355572315">"Nabíjení, <xliff:g id="NUMBER">%d</xliff:g> <xliff:g id="PERCENT">%%</xliff:g>"</string>
+ <string name="lockscreen_plugged_in" msgid="8057762828355572315">"Nabíjení - <xliff:g id="NUMBER">%d</xliff:g> <xliff:g id="PERCENT">%%</xliff:g>"</string>
<string name="lockscreen_charged" msgid="4938930459620989972">"nabito"</string>
<string name="lockscreen_battery_short" msgid="4477264849386850266">"<xliff:g id="NUMBER">%d</xliff:g> <xliff:g id="PERCENT">%%</xliff:g>"</string>
<string name="lockscreen_low_battery" msgid="1482873981919249740">"Připojte dobíjecí zařízení."</string>
@@ -853,15 +855,21 @@
<string name="searchview_description_clear" msgid="1330281990951833033">"Smazat dotaz"</string>
<string name="searchview_description_submit" msgid="2688450133297983542">"Odeslat dotaz"</string>
<string name="searchview_description_voice" msgid="2453203695674994440">"Hlasové vyhledávání"</string>
+ <!-- no translation found for enable_explore_by_touch_warning_title (7460694070309730149) -->
+ <skip />
+ <!-- no translation found for enable_explore_by_touch_warning_message (8655887539089910577) -->
+ <skip />
+ <!-- no translation found for enable_explore_by_touch_warning_message (2708199672852373195) -->
+ <skip />
<string name="oneMonthDurationPast" msgid="7396384508953779925">"před 1 měsícem"</string>
<string name="beforeOneMonthDurationPast" msgid="909134546836499826">"Déle než před 1 měsícem"</string>
<plurals name="num_seconds_ago">
<item quantity="one" msgid="4869870056547896011">"před 1 sekundou"</item>
- <item quantity="other" msgid="3903706804349556379">"před <xliff:g id="COUNT">%d</xliff:g> sek."</item>
+ <item quantity="other" msgid="3903706804349556379">"před <xliff:g id="COUNT">%d</xliff:g> s"</item>
</plurals>
<plurals name="num_minutes_ago">
<item quantity="one" msgid="3306787433088810191">"před 1 minutou"</item>
- <item quantity="other" msgid="2176942008915455116">"před <xliff:g id="COUNT">%d</xliff:g> min."</item>
+ <item quantity="other" msgid="2176942008915455116">"před <xliff:g id="COUNT">%d</xliff:g> min"</item>
</plurals>
<plurals name="num_hours_ago">
<item quantity="one" msgid="9150797944610821849">"před 1 hodinou"</item>
@@ -882,7 +890,7 @@
</plurals>
<plurals name="in_num_minutes">
<item quantity="one" msgid="8793095251325200395">"za 1 minutu"</item>
- <item quantity="other" msgid="3330713936399448749">"za <xliff:g id="COUNT">%d</xliff:g> min."</item>
+ <item quantity="other" msgid="3330713936399448749">"za <xliff:g id="COUNT">%d</xliff:g> min"</item>
</plurals>
<plurals name="in_num_hours">
<item quantity="one" msgid="7164353342477769999">"za 1 hodinu"</item>
@@ -897,8 +905,8 @@
<item quantity="other" msgid="3699169366650930415">"před <xliff:g id="COUNT">%d</xliff:g> s"</item>
</plurals>
<plurals name="abbrev_num_minutes_ago">
- <item quantity="one" msgid="6361490147113871545">"před 1 min."</item>
- <item quantity="other" msgid="851164968597150710">"před <xliff:g id="COUNT">%d</xliff:g> min."</item>
+ <item quantity="one" msgid="6361490147113871545">"před 1 min"</item>
+ <item quantity="other" msgid="851164968597150710">"před <xliff:g id="COUNT">%d</xliff:g> min"</item>
</plurals>
<plurals name="abbrev_num_hours_ago">
<item quantity="one" msgid="4796212039724722116">"před 1 hodinou"</item>
@@ -913,8 +921,8 @@
<item quantity="other" msgid="5495880108825805108">"za <xliff:g id="COUNT">%d</xliff:g> s"</item>
</plurals>
<plurals name="abbrev_in_num_minutes">
- <item quantity="one" msgid="562786149928284878">"za 1 min."</item>
- <item quantity="other" msgid="4216113292706568726">"za <xliff:g id="COUNT">%d</xliff:g> min."</item>
+ <item quantity="one" msgid="562786149928284878">"za 1 min"</item>
+ <item quantity="other" msgid="4216113292706568726">"za <xliff:g id="COUNT">%d</xliff:g> min"</item>
</plurals>
<plurals name="abbrev_in_num_hours">
<item quantity="one" msgid="3274708118124045246">"za 1 hodinu"</item>
@@ -931,8 +939,8 @@
<string name="days" msgid="4774547661021344602">"d."</string>
<string name="hour" msgid="2126771916426189481">"hodina"</string>
<string name="hours" msgid="894424005266852993">"hod."</string>
- <string name="minute" msgid="9148878657703769868">"min."</string>
- <string name="minutes" msgid="5646001005827034509">"min."</string>
+ <string name="minute" msgid="9148878657703769868">"min"</string>
+ <string name="minutes" msgid="5646001005827034509">"min"</string>
<string name="second" msgid="3184235808021478">"s"</string>
<string name="seconds" msgid="3161515347216589235">"s"</string>
<string name="week" msgid="5617961537173061583">"týden"</string>
@@ -976,7 +984,7 @@
<string name="capital_off" msgid="6815870386972805832">"O"</string>
<string name="whichApplication" msgid="4533185947064773386">"Dokončit akci pomocí aplikace"</string>
<string name="alwaysUse" msgid="4583018368000610438">"Použít jako výchozí nastavení pro tuto činnost."</string>
- <string name="clearDefaultHintMsg" msgid="3252584689512077257">"Výchozí nastavení vymažete v části Nastavení systému &gt; Aplikace &gt; Stažené."</string>
+ <string name="clearDefaultHintMsg" msgid="3252584689512077257">"Výchozí nastavení vymažete v sekci Nastavení systému &gt; Aplikace &gt; Stažené."</string>
<string name="chooseActivity" msgid="7486876147751803333">"Vyberte činnost"</string>
<string name="chooseUsbActivity" msgid="6894748416073583509">"Vyberte aplikaci pro zařízení USB"</string>
<string name="noApplications" msgid="2991814273936504689">"Tuto činnost nemohou provádět žádné aplikace."</string>
@@ -997,7 +1005,7 @@
<string name="launch_warning_original" msgid="188102023021668683">"Původně byla spuštěna aplikace <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
<string name="screen_compat_mode_scale" msgid="3202955667675944499">"Měřítko"</string>
<string name="screen_compat_mode_show" msgid="4013878876486655892">"Vždy zobrazovat"</string>
- <string name="screen_compat_mode_hint" msgid="1064524084543304459">"Tento režim znovu povolíte v části Nastavení systému &gt; Aplikace &gt; Stažené."</string>
+ <string name="screen_compat_mode_hint" msgid="1064524084543304459">"Tento režim znovu povolíte v sekci Nastavení systému &gt; Aplikace &gt; Stažené."</string>
<string name="smv_application" msgid="3307209192155442829">"Aplikace <xliff:g id="APPLICATION">%1$s</xliff:g> (proces <xliff:g id="PROCESS">%2$s</xliff:g>) porušila své vlastní vynucené zásady StrictMode."</string>
<string name="smv_process" msgid="5120397012047462446">"Proces <xliff:g id="PROCESS">%1$s</xliff:g> porušil své vlastní vynucené zásady StrictMode."</string>
<string name="android_upgrading_title" msgid="1584192285441405746">"Android se upgraduje..."</string>
@@ -1083,7 +1091,7 @@
<string name="perms_new_perm_prefix" msgid="8257740710754301407"><font size="12" fgcolor="#ff900000">"NOVÉ: "</font></string>
<string name="perms_description_app" msgid="5139836143293299417">"Poskytuje: <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
<string name="no_permissions" msgid="7283357728219338112">"Nejsou vyžadována žádná oprávnění"</string>
- <string name="usb_storage_activity_title" msgid="4465055157209648641">"Velkokapacitní paměťové zařízení USB"</string>
+ <string name="usb_storage_activity_title" msgid="4465055157209648641">"Velkokapacitní úložiště USB"</string>
<string name="usb_storage_title" msgid="5901459041398751495">"USB připojeno"</string>
<string name="usb_storage_message" product="nosdcard" msgid="3308538094316477839">"Připojili jste se k počítači pomocí rozhraní USB. Chcete-li kopírovat soubory z počítače do úložiště USB v zařízení Android či obráceně, klepněte na tlačítko níže."</string>
<string name="usb_storage_message" product="default" msgid="805351000446037811">"Připojili jste se k počítači pomocí rozhraní USB. Chcete-li kopírovat soubory z počítače na kartu SD v zařízení Android či obráceně, stiskněte tlačítko níže."</string>
@@ -1115,10 +1123,14 @@
<string name="extmedia_format_button_format" msgid="4131064560127478695">"Formátovat"</string>
<string name="adb_active_notification_title" msgid="6729044778949189918">"Ladění přes rozhraní USB připojeno"</string>
<string name="adb_active_notification_message" msgid="1016654627626476142">"Dotykem zakážete ladění USB."</string>
- <string name="select_input_method" msgid="4653387336791222978">"Vybrat metodu vstupu"</string>
- <string name="configure_input_methods" msgid="9091652157722495116">"Nastavit metody vstupu"</string>
+ <string name="select_input_method" msgid="4653387336791222978">"Vybrat metodu zadávání"</string>
+ <string name="configure_input_methods" msgid="9091652157722495116">"Nastavit metody zadávání"</string>
<string name="use_physical_keyboard" msgid="6203112478095117625">"Fyzická klávesnice"</string>
<string name="hardware" msgid="7517821086888990278">"Hardware"</string>
+ <!-- no translation found for select_keyboard_layout_notification_title (1407367017263030773) -->
+ <skip />
+ <!-- no translation found for select_keyboard_layout_notification_message (4465907700449257063) -->
+ <skip />
<string name="fast_scroll_alphabet" msgid="5433275485499039199">" AÁBCČDĎEÉĚFGHCHIÍJKLMNŇOÓPQRŘSŠTŤUÚVWXYÝZŽ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789AÁBCČDĎEÉĚFGHCHIÍJKLMNŇOÓPQRŘSŠTŤUÚVWXYÝZŽ"</string>
<string name="candidates_style" msgid="4333913089637062257"><u>"kandidáti"</u></string>
@@ -1193,7 +1205,7 @@
<string name="throttled_notification_title" msgid="6269541897729781332">"Byl překročen limit mobilních dat"</string>
<string name="throttled_notification_message" msgid="5443457321354907181">"Dotykem zobrazíte další informace o využití mobilních dat."</string>
<string name="no_matches" msgid="8129421908915840737">"Žádné shody"</string>
- <string name="find_on_page" msgid="1946799233822820384">"Vyhledat na stránce"</string>
+ <string name="find_on_page" msgid="1946799233822820384">"Hledat na stránce"</string>
<plurals name="matches_found">
<item quantity="one" msgid="8167147081136579439">"1 shoda"</item>
<item quantity="other" msgid="4641872797067609177">"<xliff:g id="INDEX">%d</xliff:g> z <xliff:g id="TOTAL">%d</xliff:g>"</item>
@@ -1312,5 +1324,6 @@
<string name="launchBrowserDefault" msgid="2057951947297614725">"Spustit prohlížeč?"</string>
<string name="SetupCallDefault" msgid="5834948469253758575">"Přijmout hovor?"</string>
<string name="activity_resolver_use_always" msgid="8017770747801494933">"Vždy"</string>
- <string name="activity_resolver_use_once" msgid="405646673463328329">"Pouze jednou"</string>
+ <!-- no translation found for activity_resolver_use_once (2404644797149173758) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml
index 4ec0197..9dc89a0 100644
--- a/core/res/res/values-da/strings.xml
+++ b/core/res/res/values-da/strings.xml
@@ -317,6 +317,8 @@
<string name="permdesc_readInputState" msgid="8387754901688728043">"Tillader, at appen kan se de taster, som du trykker på, selv i en anden app (såsom indtastning af adgangskode). Dette bør aldrig være nødvendigt for normale apps."</string>
<string name="permlab_bindInputMethod" msgid="3360064620230515776">"forpligt til en inputmetode"</string>
<string name="permdesc_bindInputMethod" msgid="3250440322807286331">"Tillader, at brugeren kan forpligter sig til en inputmetodes grænseflade på øverste niveau. Bør aldrig være nødvendigt til almindelige apps."</string>
+ <string name="permlab_bindAccessibilityService" msgid="5357733942556031593">"bind dig til en tilgængelighedstjeneste"</string>
+ <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Tillader, at brugeren binder sig til en grænseflade for en tilgængelighedstjeneste på øverste niveau. Bør aldrig være nødvendigt til almindelige apps."</string>
<string name="permlab_bindTextService" msgid="7358378401915287938">"forpligte sig til en sms-tjeneste"</string>
<string name="permdesc_bindTextService" msgid="8151968910973998670">"Tillader, at ejeren kan binde en teksttjenestes grænseflade (f. eks. SpellCheckerService) på øverste niveau. Dette bør aldrig være nødvendigt til normale apps."</string>
<string name="permlab_bindVpnService" msgid="4708596021161473255">"bind til en VPN-tjeneste"</string>
@@ -853,6 +855,12 @@
<string name="searchview_description_clear" msgid="1330281990951833033">"Ryd forespørgslen"</string>
<string name="searchview_description_submit" msgid="2688450133297983542">"Indsend forespørgslen"</string>
<string name="searchview_description_voice" msgid="2453203695674994440">"Stemmesøgning"</string>
+ <!-- no translation found for enable_explore_by_touch_warning_title (7460694070309730149) -->
+ <skip />
+ <!-- no translation found for enable_explore_by_touch_warning_message (8655887539089910577) -->
+ <skip />
+ <!-- no translation found for enable_explore_by_touch_warning_message (2708199672852373195) -->
+ <skip />
<string name="oneMonthDurationPast" msgid="7396384508953779925">"For 1 måned siden"</string>
<string name="beforeOneMonthDurationPast" msgid="909134546836499826">"Før for 1 måned siden"</string>
<plurals name="num_seconds_ago">
@@ -1119,6 +1127,10 @@
<string name="configure_input_methods" msgid="9091652157722495116">"Konfigurer inputmetoder"</string>
<string name="use_physical_keyboard" msgid="6203112478095117625">"Fysisk tastatur"</string>
<string name="hardware" msgid="7517821086888990278">"Hardware"</string>
+ <!-- no translation found for select_keyboard_layout_notification_title (1407367017263030773) -->
+ <skip />
+ <!-- no translation found for select_keyboard_layout_notification_message (4465907700449257063) -->
+ <skip />
<string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="candidates_style" msgid="4333913089637062257"><u>"kandidater"</u></string>
@@ -1312,5 +1324,6 @@
<string name="launchBrowserDefault" msgid="2057951947297614725">"Vil du starte browseren?"</string>
<string name="SetupCallDefault" msgid="5834948469253758575">"Vil du besvare opkaldet?"</string>
<string name="activity_resolver_use_always" msgid="8017770747801494933">"Altid"</string>
- <string name="activity_resolver_use_once" msgid="405646673463328329">"Kun denne ene gang"</string>
+ <!-- no translation found for activity_resolver_use_once (2404644797149173758) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml
index 4ca2b86..ec8ca3e 100644
--- a/core/res/res/values-de/strings.xml
+++ b/core/res/res/values-de/strings.xml
@@ -317,6 +317,8 @@
<string name="permdesc_readInputState" msgid="8387754901688728043">"Ermöglicht der App, die von Ihnen gedrückten Tasten zu überwachen, etwa bei der Eingabe eines Passworts. Dies gilt auch für die Interaktion mit anderen Apps. Sollte nie für normale Apps benötigt werden."</string>
<string name="permlab_bindInputMethod" msgid="3360064620230515776">"An eine Eingabemethode binden"</string>
<string name="permdesc_bindInputMethod" msgid="3250440322807286331">"Ermöglicht dem Halter, sich an die Oberfläche einer Eingabemethode auf oberster Ebene zu binden. Sollte nie für normale Apps benötigt werden."</string>
+ <string name="permlab_bindAccessibilityService" msgid="5357733942556031593">"An eine Bedienungshilfe binden"</string>
+ <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Ermöglicht dem Halter, sich an die Oberfläche einer Bedienungshilfe auf oberster Ebene zu binden. Sollte nie für normale Apps benötigt werden."</string>
<string name="permlab_bindTextService" msgid="7358378401915287938">"An einen Textdienst binden"</string>
<string name="permdesc_bindTextService" msgid="8151968910973998670">"Ermöglicht dem Halter, sich an die Oberfläche eines Textdienstes auf oberster Ebene zu binden, z. B. eines Rechtschreibprüfungsdienstes. Sollte nie für normale Apps benötigt werden."</string>
<string name="permlab_bindVpnService" msgid="4708596021161473255">"An einen VPN-Dienst binden"</string>
@@ -409,10 +411,10 @@
<string name="permdesc_accessLocationExtraCommands" msgid="6737736970602176133">"Ermöglicht der App, auf zusätzliche Standortanbieterbefehle zuzugreifen. Schädliche Apps können so die Funktionsweise von GPS oder anderen Standortquellen beeinträchtigen."</string>
<string name="permlab_installLocationProvider" msgid="6578101199825193873">"Berechtigung zur Installation eines Standortanbieters"</string>
<string name="permdesc_installLocationProvider" msgid="1742577679350078373">"Erstellt simulierte Standortquellen für Testzwecke. Schädliche Apps können so den von echten Standortquellen wie GPS oder Netzwerkanbietern zurückgegebenen Standort und/oder Status überschreiben oder Ihren Standort überwachen und an eine externe Quelle weitergeben."</string>
- <string name="permlab_accessFineLocation" msgid="8116127007541369477">"genauer (GPS-) Standort"</string>
+ <string name="permlab_accessFineLocation" msgid="8116127007541369477">"Genauer (GPS-) Standort"</string>
<string name="permdesc_accessFineLocation" product="tablet" msgid="5326423948268164934">"Ermöglicht Zugriff auf genaue Standortquellen wie GPS auf dem Tablet (falls verfügbar). Schädliche Apps können damit bestimmen, wo Sie sich befinden, und so Ihren Akku zusätzlich belasten."</string>
<string name="permdesc_accessFineLocation" product="default" msgid="7130267914433890869">"Ermöglicht Zugriff auf genaue Standortquellen wie GPS auf dem Telefon (falls verfügbar). Schädliche Apps können damit bestimmen, wo Sie sich befinden, und so Ihren Akku zusätzlich belasten."</string>
- <string name="permlab_accessCoarseLocation" msgid="4642255009181975828">"ungefährer (netzwerkbasierter) Standort"</string>
+ <string name="permlab_accessCoarseLocation" msgid="4642255009181975828">"Ungefährer (netzwerkbasierter) Standort"</string>
<string name="permdesc_accessCoarseLocation" product="tablet" msgid="5460726396318105483">"Ermöglicht Zugriff auf Quellen mit ungefähren Standortbestimmungen wie die Datenbank des Mobilfunknetzes, um falls möglich den ungefähren Standort des Tablets zu bestimmen. Schädliche Apps können so herausfinden, wo Sie sich ungefähr befinden."</string>
<string name="permdesc_accessCoarseLocation" product="default" msgid="8900795778057579522">"Ermöglicht Zugriff auf Quellen mit ungefähren Standortbestimmungen wie die Datenbank des Mobilfunknetzes, um falls möglich den ungefähren Standort des Telefons zu bestimmen. Schädliche Apps können so herauszufinden, wo Sie sich ungefähr befinden."</string>
<string name="permlab_accessSurfaceFlinger" msgid="2363969641792388947">"Auf SurfaceFlinger zugreifen"</string>
@@ -548,9 +550,9 @@
<string name="permdesc_writeSyncSettings" msgid="1466056564502117130">"Ermöglicht der App, die Synchronisierungseinstellungen zu ändern, etwa ob die Synchronisierung für die App \"Personen\" aktiviert ist oder nicht"</string>
<string name="permlab_readSyncStats" msgid="7396577451360202448">"Synchronisierungsstatistiken lesen"</string>
<string name="permdesc_readSyncStats" msgid="3801971839939951678">"Ermöglicht der App, die Synchronisierungsstatistiken zu lesen, etwa den Verlauf der bereits durchgeführten Synchronisierungen"</string>
- <string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"abonnierte Feeds lesen"</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="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="8977815988329283705">"Ermöglicht der App, alle privaten Wörter, Namen und Ausdrücke zu lesen, die ein Nutzer in seinem Wörterbuch gespeichert hat"</string>
@@ -853,6 +855,12 @@
<string name="searchview_description_clear" msgid="1330281990951833033">"Anfrage löschen"</string>
<string name="searchview_description_submit" msgid="2688450133297983542">"Anfrage senden"</string>
<string name="searchview_description_voice" msgid="2453203695674994440">"Sprachsuche"</string>
+ <!-- no translation found for enable_explore_by_touch_warning_title (7460694070309730149) -->
+ <skip />
+ <!-- no translation found for enable_explore_by_touch_warning_message (8655887539089910577) -->
+ <skip />
+ <!-- no translation found for enable_explore_by_touch_warning_message (2708199672852373195) -->
+ <skip />
<string name="oneMonthDurationPast" msgid="7396384508953779925">"Vor 1 Monat"</string>
<string name="beforeOneMonthDurationPast" msgid="909134546836499826">"Vor mehr als 1 Monat"</string>
<plurals name="num_seconds_ago">
@@ -1119,6 +1127,10 @@
<string name="configure_input_methods" msgid="9091652157722495116">"Eingabemethoden einrichten"</string>
<string name="use_physical_keyboard" msgid="6203112478095117625">"Physische Tastatur"</string>
<string name="hardware" msgid="7517821086888990278">"Hardware"</string>
+ <!-- no translation found for select_keyboard_layout_notification_title (1407367017263030773) -->
+ <skip />
+ <!-- no translation found for select_keyboard_layout_notification_message (4465907700449257063) -->
+ <skip />
<string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="candidates_style" msgid="4333913089637062257"><u>"Kandidaten"</u></string>
@@ -1193,7 +1205,7 @@
<string name="throttled_notification_title" msgid="6269541897729781332">"Mobildatenlimit überschritten"</string>
<string name="throttled_notification_message" msgid="5443457321354907181">"Durch Berühren weitere Informationen zum Mobildatenverbrauch aufrufen"</string>
<string name="no_matches" msgid="8129421908915840737">"Keine Treffer"</string>
- <string name="find_on_page" msgid="1946799233822820384">"Suchen"</string>
+ <string name="find_on_page" msgid="1946799233822820384">"Auf Seite suchen"</string>
<plurals name="matches_found">
<item quantity="one" msgid="8167147081136579439">"1 Treffer"</item>
<item quantity="other" msgid="4641872797067609177">"<xliff:g id="INDEX">%d</xliff:g> von <xliff:g id="TOTAL">%d</xliff:g>"</item>
@@ -1312,5 +1324,6 @@
<string name="launchBrowserDefault" msgid="2057951947297614725">"Browser starten?"</string>
<string name="SetupCallDefault" msgid="5834948469253758575">"Anruf annehmen?"</string>
<string name="activity_resolver_use_always" msgid="8017770747801494933">"Immer"</string>
- <string name="activity_resolver_use_once" msgid="405646673463328329">"Nur einmal"</string>
+ <!-- no translation found for activity_resolver_use_once (2404644797149173758) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml
index 08e2389..8cde21f 100644
--- a/core/res/res/values-el/strings.xml
+++ b/core/res/res/values-el/strings.xml
@@ -317,6 +317,8 @@
<string name="permdesc_readInputState" msgid="8387754901688728043">"Επιτρέπει στην εφαρμογή να παρακολουθεί τα πλήκτρα που πατάτε, ακόμη και σε μια άλλη εφαρμογή (όπως π.χ. η καταχώρηση ενός κωδικού πρόσβασης). Δεν απαιτείται για συνήθεις εφαρμογές."</string>
<string name="permlab_bindInputMethod" msgid="3360064620230515776">"δέσμευση σε μέθοδο εισόδου"</string>
<string name="permdesc_bindInputMethod" msgid="3250440322807286331">"Επιτρέπει στον κάτοχο τη δέσμευση στη διεπαφή ανωτάτου επιπέδου μιας μεθόδου εισόδου. Δεν απαιτείται για συνήθεις εφαρμογές."</string>
+ <string name="permlab_bindAccessibilityService" msgid="5357733942556031593">"δέσμευση σε υπηρεσία προσβασιμότητας"</string>
+ <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Επιτρέπει στον κάτοχο τη δέσμευση στη διεπαφή ανώτατου επιπέδου μιας υπηρεσίας προσβασιμότητας. Δεν απαιτείται σε κανονικές εφαρμογές."</string>
<string name="permlab_bindTextService" msgid="7358378401915287938">"δέσμευση σε υπηρεσία ανταλλαγής μηνυμάτων"</string>
<string name="permdesc_bindTextService" msgid="8151968910973998670">"Επιτρέπει στον κάτοχο τη σύνδεση με τη διεπαφή ανωτέρου επιπέδου μιας υπηρεσίας ανταλλαγής μηνυμάτων (π.χ. SpellCheckerService). Δεν είναι απαραίτητο για κανονικές εφαρμογές."</string>
<string name="permlab_bindVpnService" msgid="4708596021161473255">"δέσμευση σε υπηρεσία VPN"</string>
@@ -853,6 +855,9 @@
<string name="searchview_description_clear" msgid="1330281990951833033">"Απαλοιφή ερωτήματος"</string>
<string name="searchview_description_submit" msgid="2688450133297983542">"Υποβολή ερωτήματος"</string>
<string name="searchview_description_voice" msgid="2453203695674994440">"Φωνητική αναζήτηση"</string>
+ <string name="enable_explore_by_touch_warning_title" msgid="7460694070309730149">"Ενεργοποίηση Αναζήτησης μέσω αφής;"</string>
+ <string name="enable_explore_by_touch_warning_message" product="tablet" msgid="8655887539089910577">"Η υπηρεσία <xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> απαιτεί ενεργοποίηση της Εξερεύνησης μέσω αφής. Όταν είναι ενεργοποιημένη η Εξερεύνηση μέσω αφής, μπορείτε να δείτε ή να ακούσετε περιγραφές για τις επιλογές που βρίσκονται κάτω από το δάχτυλό σας ή να κάνετε κινήσεις αλληλεπίδρασης με το tablet σας."</string>
+ <string name="enable_explore_by_touch_warning_message" product="default" msgid="2708199672852373195">"Η υπηρεσία <xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> απαιτεί ενεργοποίηση της Εξερεύνησης μέσω αφής. Όταν είναι ενεργοποιημένη η Εξερεύνηση μέσω αφής, μπορείτε να δείτε ή να ακούσετε περιγραφές για τις επιλογές που βρίσκονται κάτω από το δάχτυλό σας ή να κάνετε κινήσεις αλληλεπίδρασης με το τηλέφωνό σας."</string>
<string name="oneMonthDurationPast" msgid="7396384508953779925">"πριν από 1 μήνα"</string>
<string name="beforeOneMonthDurationPast" msgid="909134546836499826">"Παλαιότερα από 1 μήνα"</string>
<plurals name="num_seconds_ago">
@@ -1119,6 +1124,8 @@
<string name="configure_input_methods" msgid="9091652157722495116">"Ρύθμιση μεθόδων εισαγωγής"</string>
<string name="use_physical_keyboard" msgid="6203112478095117625">"Φυσικό πληκτρολόγιο"</string>
<string name="hardware" msgid="7517821086888990278">"Υλικό"</string>
+ <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"Επιλογή διάταξης πληκτρολογίου"</string>
+ <string name="select_keyboard_layout_notification_message" msgid="4465907700449257063">"Αγγίξτε για να επιλέξετε διάταξη πληκτρολογίου."</string>
<string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="candidates_style" msgid="4333913089637062257"><u>"υποψήφιοι"</u></string>
@@ -1312,5 +1319,5 @@
<string name="launchBrowserDefault" msgid="2057951947297614725">"Εκκίνηση προγράμματος περιήγησης;"</string>
<string name="SetupCallDefault" msgid="5834948469253758575">"Αποδοχή κλήσης;"</string>
<string name="activity_resolver_use_always" msgid="8017770747801494933">"Πάντα"</string>
- <string name="activity_resolver_use_once" msgid="405646673463328329">"Μόνο μία φορά"</string>
+ <string name="activity_resolver_use_once" msgid="2404644797149173758">"Μόνο μία φορά"</string>
</resources>
diff --git a/core/res/res/values-en-rGB/strings.xml b/core/res/res/values-en-rGB/strings.xml
index c991437..4ad7daf 100644
--- a/core/res/res/values-en-rGB/strings.xml
+++ b/core/res/res/values-en-rGB/strings.xml
@@ -317,6 +317,8 @@
<string name="permdesc_readInputState" msgid="8387754901688728043">"Allows the app to watch the keys that you press even when interacting with another app (such as typing a password). Should never be needed for normal apps."</string>
<string name="permlab_bindInputMethod" msgid="3360064620230515776">"bind to an input method"</string>
<string name="permdesc_bindInputMethod" msgid="3250440322807286331">"Allows the holder to bind to the top-level interface of an input method. Should never be needed for normal apps."</string>
+ <string name="permlab_bindAccessibilityService" msgid="5357733942556031593">"bind to an accessibility service"</string>
+ <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Allows the holder to bind to the top-level interface of an accessibility service. Should never be needed for normal apps."</string>
<string name="permlab_bindTextService" msgid="7358378401915287938">"bind to a text service"</string>
<string name="permdesc_bindTextService" msgid="8151968910973998670">"Allows the holder to bind to the top-level interface of a text service (e.g. SpellCheckerService). Should never be needed for normal applications."</string>
<string name="permlab_bindVpnService" msgid="4708596021161473255">"bind to a VPN service"</string>
@@ -853,6 +855,9 @@
<string name="searchview_description_clear" msgid="1330281990951833033">"Clear query"</string>
<string name="searchview_description_submit" msgid="2688450133297983542">"Submit query"</string>
<string name="searchview_description_voice" msgid="2453203695674994440">"Voice search"</string>
+ <string name="enable_explore_by_touch_warning_title" msgid="7460694070309730149">"Enable Explore by Touch?"</string>
+ <string name="enable_explore_by_touch_warning_message" product="tablet" msgid="8655887539089910577">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> wants to enable Explore by Touch. When Explore by Touch is turned on, you can hear or see descriptions of what\'s under your finger or perform gestures to interact with the tablet."</string>
+ <string name="enable_explore_by_touch_warning_message" product="default" msgid="2708199672852373195">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> wants to enable Explore by Touch. When Explore by Touch is turned on, you can hear or see descriptions of what\'s under your finger or perform gestures to interact with the phone."</string>
<string name="oneMonthDurationPast" msgid="7396384508953779925">"1 month ago"</string>
<string name="beforeOneMonthDurationPast" msgid="909134546836499826">"Before 1 month ago"</string>
<plurals name="num_seconds_ago">
@@ -1119,6 +1124,8 @@
<string name="configure_input_methods" msgid="9091652157722495116">"Set up input methods"</string>
<string name="use_physical_keyboard" msgid="6203112478095117625">"Physical keyboard"</string>
<string name="hardware" msgid="7517821086888990278">"Hardware"</string>
+ <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"Select keyboard layout"</string>
+ <string name="select_keyboard_layout_notification_message" msgid="4465907700449257063">"Touch to select a keyboard layout."</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>"candidates"</u></string>
@@ -1312,5 +1319,5 @@
<string name="launchBrowserDefault" msgid="2057951947297614725">"Launch Browser?"</string>
<string name="SetupCallDefault" msgid="5834948469253758575">"Accept call?"</string>
<string name="activity_resolver_use_always" msgid="8017770747801494933">"Always"</string>
- <string name="activity_resolver_use_once" msgid="405646673463328329">"Just Once"</string>
+ <string name="activity_resolver_use_once" msgid="2404644797149173758">"Just once"</string>
</resources>
diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml
index 72132dd..4d861fc 100644
--- a/core/res/res/values-es-rUS/strings.xml
+++ b/core/res/res/values-es-rUS/strings.xml
@@ -317,6 +317,8 @@
<string name="permdesc_readInputState" msgid="8387754901688728043">"Permite que la aplicación observe las teclas que presionas, incluso al interactuar con otra aplicación (como cuando escribes una contraseña). Las aplicaciones normales no deberían necesitar este permiso."</string>
<string name="permlab_bindInputMethod" msgid="3360064620230515776">"vincular a un método de entrada"</string>
<string name="permdesc_bindInputMethod" msgid="3250440322807286331">"Permite al propietario vincularse a la interfaz de nivel superior de un método de entrada. Las aplicaciones normales no deberían necesitar este permiso."</string>
+ <string name="permlab_bindAccessibilityService" msgid="5357733942556031593">"vincular a un servicio de accesibilidad"</string>
+ <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Permite al propietario vincularse a la interfaz de nivel superior de un servicio de accesibilidad. Las aplicaciones normales no deberían necesitar este permiso."</string>
<string name="permlab_bindTextService" msgid="7358378401915287938">"vincular a un servicio de texto"</string>
<string name="permdesc_bindTextService" msgid="8151968910973998670">"Permite al titular vincularse a la interfaz de nivel superior de un servicio de texto (p. ej., SpellCheckerService). Las aplicaciones normales no deberían necesitar este permiso."</string>
<string name="permlab_bindVpnService" msgid="4708596021161473255">"vincular con un servicio de VPN"</string>
@@ -731,7 +733,7 @@
<string name="lockscreen_password_wrong" msgid="5737815393253165301">"Volver a intentarlo"</string>
<string name="faceunlock_multiple_failures" msgid="754137583022792429">"Se superó el máximo de intentos permitido para el desbloqueo facial del dispositivo."</string>
<string name="lockscreen_plugged_in" msgid="8057762828355572315">"Cargando <xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
- <string name="lockscreen_charged" msgid="4938930459620989972">"Cargada."</string>
+ <string name="lockscreen_charged" msgid="4938930459620989972">"Cargado."</string>
<string name="lockscreen_battery_short" msgid="4477264849386850266">"<xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
<string name="lockscreen_low_battery" msgid="1482873981919249740">"Conecta tu cargador."</string>
<string name="lockscreen_missing_sim_message_short" msgid="7381499217732227295">"No hay tarjeta SIM."</string>
@@ -853,6 +855,9 @@
<string name="searchview_description_clear" msgid="1330281990951833033">"Eliminar la consulta"</string>
<string name="searchview_description_submit" msgid="2688450133297983542">"Enviar consulta"</string>
<string name="searchview_description_voice" msgid="2453203695674994440">"Búsqueda por voz"</string>
+ <string name="enable_explore_by_touch_warning_title" msgid="7460694070309730149">"¿Habilitar exploración táctil?"</string>
+ <string name="enable_explore_by_touch_warning_message" product="tablet" msgid="8655887539089910577">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> quiere habilitar la exploración táctil. Cuando esta función esté activada, podrás escuchar o ver descripciones del contenido seleccionado o usar gestos para interactuar con la tableta."</string>
+ <string name="enable_explore_by_touch_warning_message" product="default" msgid="2708199672852373195">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> quiere habilitar la exploración táctil. Cuando esta función esté activada, podrás escuchar o ver descripciones del contenido seleccionado o usar gestos para interactuar con el teléfono."</string>
<string name="oneMonthDurationPast" msgid="7396384508953779925">"hace 1 mes"</string>
<string name="beforeOneMonthDurationPast" msgid="909134546836499826">"Anterior a 1 mes atrás"</string>
<plurals name="num_seconds_ago">
@@ -1081,7 +1086,7 @@
<string name="date_time_set" msgid="5777075614321087758">"Establecer"</string>
<string name="date_time_done" msgid="2507683751759308828">"Listo"</string>
<string name="perms_new_perm_prefix" msgid="8257740710754301407"><font size="12" fgcolor="#ff900000">"NUEVO: "</font></string>
- <string name="perms_description_app" msgid="5139836143293299417">"Proporcionado por <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
+ <string name="perms_description_app" msgid="5139836143293299417">"Proporcionado por <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="no_permissions" msgid="7283357728219338112">"No se requieren permisos"</string>
<string name="usb_storage_activity_title" msgid="4465055157209648641">"Almacenamiento USB masivo"</string>
<string name="usb_storage_title" msgid="5901459041398751495">"Conectado al USB"</string>
@@ -1115,10 +1120,12 @@
<string name="extmedia_format_button_format" msgid="4131064560127478695">"Formato"</string>
<string name="adb_active_notification_title" msgid="6729044778949189918">"Depuración de USB conectada"</string>
<string name="adb_active_notification_message" msgid="1016654627626476142">"Toca para desactivar la depuración de USB."</string>
- <string name="select_input_method" msgid="4653387336791222978">"Selecciona el método de introducción"</string>
+ <string name="select_input_method" msgid="4653387336791222978">"Selecciona el método de entrada"</string>
<string name="configure_input_methods" msgid="9091652157722495116">"Configurar métodos de introducción"</string>
<string name="use_physical_keyboard" msgid="6203112478095117625">"Teclado físico"</string>
<string name="hardware" msgid="7517821086888990278">"Hardware"</string>
+ <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"Selecciona un diseño de teclado"</string>
+ <string name="select_keyboard_layout_notification_message" msgid="4465907700449257063">"Toca para seleccionar un diseño de teclado."</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>"candidatos"</u></string>
@@ -1312,5 +1319,5 @@
<string name="launchBrowserDefault" msgid="2057951947297614725">"¿Deseas iniciar el navegador?"</string>
<string name="SetupCallDefault" msgid="5834948469253758575">"¿Aceptar la llamada?"</string>
<string name="activity_resolver_use_always" msgid="8017770747801494933">"Siempre"</string>
- <string name="activity_resolver_use_once" msgid="405646673463328329">"Solo una vez"</string>
+ <string name="activity_resolver_use_once" msgid="2404644797149173758">"Solo una vez"</string>
</resources>
diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml
index ea1f3c4..f5d8795 100644
--- a/core/res/res/values-es/strings.xml
+++ b/core/res/res/values-es/strings.xml
@@ -317,6 +317,8 @@
<string name="permdesc_readInputState" msgid="8387754901688728043">"Permite que la aplicación sepa las teclas que pulsas incluso cuando interactúas con otra aplicación (como, por ejemplo, al introducir una contraseña). Nunca debería ser necesario para las aplicaciones normales."</string>
<string name="permlab_bindInputMethod" msgid="3360064620230515776">"enlazar con un método de introducción de texto"</string>
<string name="permdesc_bindInputMethod" msgid="3250440322807286331">"Permite que se enlace con la interfaz de nivel superior de un método de introducción de texto. Las aplicaciones normales no deberían necesitar este permiso."</string>
+ <string name="permlab_bindAccessibilityService" msgid="5357733942556031593">"enlazar con un servicio de accesibilidad"</string>
+ <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Permite enlazar con la interfaz de nivel superior de un servicio de accesibilidad. Las aplicaciones normales no deberían necesitar este permiso."</string>
<string name="permlab_bindTextService" msgid="7358378401915287938">"enlazar con un servicio de texto"</string>
<string name="permdesc_bindTextService" msgid="8151968910973998670">"Permite enlazar con la interfaz de nivel superior de un servicio de texto (por ejemplo, SpellCheckerService). Las aplicaciones normales no deberían necesitar este permiso."</string>
<string name="permlab_bindVpnService" msgid="4708596021161473255">"enlazar con un servicio VPN"</string>
@@ -673,7 +675,7 @@
<string name="postalTypeHome" msgid="8165756977184483097">"Casa"</string>
<string name="postalTypeWork" msgid="5268172772387694495">"Trabajo"</string>
<string name="postalTypeOther" msgid="2726111966623584341">"Otro"</string>
- <string name="imTypeCustom" msgid="2074028755527826046">"Personalizada"</string>
+ <string name="imTypeCustom" msgid="2074028755527826046">"Personalizado"</string>
<string name="imTypeHome" msgid="6241181032954263892">"Casa"</string>
<string name="imTypeWork" msgid="1371489290242433090">"Trabajo"</string>
<string name="imTypeOther" msgid="5377007495735915478">"Otro"</string>
@@ -727,8 +729,8 @@
<string name="lockscreen_emergency_call" msgid="5347633784401285225">"Llamada de emergencia"</string>
<string name="lockscreen_return_to_call" msgid="5244259785500040021">"Volver a llamada"</string>
<string name="lockscreen_pattern_correct" msgid="9039008650362261237">"Correcto"</string>
- <string name="lockscreen_pattern_wrong" msgid="4317955014948108794">"Volver a intentar"</string>
- <string name="lockscreen_password_wrong" msgid="5737815393253165301">"Volver a intentar"</string>
+ <string name="lockscreen_pattern_wrong" msgid="4317955014948108794">"Vuelve a intentarlo"</string>
+ <string name="lockscreen_password_wrong" msgid="5737815393253165301">"Vuelve a intentarlo"</string>
<string name="faceunlock_multiple_failures" msgid="754137583022792429">"Se ha superado el número máximo de intentos de desbloqueo facial."</string>
<string name="lockscreen_plugged_in" msgid="8057762828355572315">"Cargando (<xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>)"</string>
<string name="lockscreen_charged" msgid="4938930459620989972">"Cargado"</string>
@@ -853,6 +855,9 @@
<string name="searchview_description_clear" msgid="1330281990951833033">"Borrar consulta"</string>
<string name="searchview_description_submit" msgid="2688450133297983542">"Enviar consulta"</string>
<string name="searchview_description_voice" msgid="2453203695674994440">"Búsqueda por voz"</string>
+ <string name="enable_explore_by_touch_warning_title" msgid="7460694070309730149">"¿Habilitar exploración táctil?"</string>
+ <string name="enable_explore_by_touch_warning_message" product="tablet" msgid="8655887539089910577">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> quiere habilitar la exploración táctil. Cuando esta función esté activada, podrás escuchar o ver descripciones del contenido seleccionado o usar gestos para interactuar con el tablet."</string>
+ <string name="enable_explore_by_touch_warning_message" product="default" msgid="2708199672852373195">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> quiere habilitar la exploración táctil. Cuando esta función esté activada, podrás escuchar o ver descripciones del contenido seleccionado o usar gestos para interactuar con el teléfono."</string>
<string name="oneMonthDurationPast" msgid="7396384508953779925">"Hace un mes"</string>
<string name="beforeOneMonthDurationPast" msgid="909134546836499826">"Hace más de un mes"</string>
<plurals name="num_seconds_ago">
@@ -925,7 +930,7 @@
<item quantity="other" msgid="2973062968038355991">"dentro de <xliff:g id="COUNT">%d</xliff:g> días"</item>
</plurals>
<string name="preposition_for_date" msgid="9093949757757445117">"el <xliff:g id="DATE">%s</xliff:g>"</string>
- <string name="preposition_for_time" msgid="5506831244263083793">"a la(s) <xliff:g id="TIME">%s</xliff:g>"</string>
+ <string name="preposition_for_time" msgid="5506831244263083793">"a las <xliff:g id="TIME">%s</xliff:g>"</string>
<string name="preposition_for_year" msgid="5040395640711867177">"en <xliff:g id="YEAR">%s</xliff:g>"</string>
<string name="day" msgid="8144195776058119424">"día"</string>
<string name="days" msgid="4774547661021344602">"días"</string>
@@ -1085,13 +1090,13 @@
<string name="no_permissions" msgid="7283357728219338112">"No es necesario ningún permiso"</string>
<string name="usb_storage_activity_title" msgid="4465055157209648641">"Almacenamiento USB masivo"</string>
<string name="usb_storage_title" msgid="5901459041398751495">"Conexión por USB"</string>
- <string name="usb_storage_message" product="nosdcard" msgid="3308538094316477839">"Has conectado el dispositivo al ordenador por USB. Toca el siguiente botón si quieres copiar archivos entre el ordenador y el almacenamiento USB del dispositivo."</string>
- <string name="usb_storage_message" product="default" msgid="805351000446037811">"Has conectado el dispositivo al ordenador por USB. Toca el siguiente botón si quieres copiar archivos entre el ordenador y la tarjeta SD del dispositivo."</string>
+ <string name="usb_storage_message" product="nosdcard" msgid="3308538094316477839">"Has conectado el dispositivo al ordenador por USB. Toca el siguiente botón si quieres transferir archivos entre el ordenador y el almacenamiento USB del dispositivo."</string>
+ <string name="usb_storage_message" product="default" msgid="805351000446037811">"Has conectado el dispositivo al ordenador por USB. Toca el siguiente botón si quieres transferir archivos entre el ordenador y la tarjeta SD del dispositivo."</string>
<string name="usb_storage_button_mount" msgid="1052259930369508235">"Activar almacenamiento USB"</string>
<string name="usb_storage_error_message" product="nosdcard" msgid="3017045217365540658">"Se ha producido un error al usar el almacenamiento USB como almacenamiento USB masivo."</string>
<string name="usb_storage_error_message" product="default" msgid="2876018512716970313">"Se ha producido un error al usar la tarjeta SD para el almacenamiento USB masivo."</string>
<string name="usb_storage_notification_title" msgid="8175892554757216525">"Conexión por USB"</string>
- <string name="usb_storage_notification_message" msgid="939822783828183763">"Toca para copiar archivos en el ordenador o del mismo."</string>
+ <string name="usb_storage_notification_message" msgid="939822783828183763">"Toca para transferir archivos"</string>
<string name="usb_storage_stop_notification_title" msgid="2336058396663516017">"Desactivar almacenamiento USB"</string>
<string name="usb_storage_stop_notification_message" msgid="1656852098555623822">"Toca para desactivar el almacenamiento USB."</string>
<string name="usb_storage_stop_title" msgid="660129851708775853">"El almacenamiento USB está en uso"</string>
@@ -1103,7 +1108,7 @@
<string name="dlg_confirm_kill_storage_users_text" msgid="5100428757107469454">"Si activas el almacenamiento USB, se detendrán algunas aplicaciones que estás usando y es posible que no estén disponibles hasta que lo desactives."</string>
<string name="dlg_error_title" msgid="7323658469626514207">"Error de funcionamiento de USB"</string>
<string name="dlg_ok" msgid="7376953167039865701">"Aceptar"</string>
- <string name="usb_mtp_notification_title" msgid="3699913097391550394">"Conectado como un dispositivo multimedia"</string>
+ <string name="usb_mtp_notification_title" msgid="3699913097391550394">"Conectado como disp. multimedia"</string>
<string name="usb_ptp_notification_title" msgid="1960817192216064833">"Conectado como una cámara"</string>
<string name="usb_cd_installer_notification_title" msgid="6774712827892090754">"Conectado como instalador"</string>
<string name="usb_accessory_notification_title" msgid="7848236974087653666">"Conectado a un accesorio USB"</string>
@@ -1113,12 +1118,14 @@
<string name="extmedia_format_message" product="nosdcard" msgid="3934016853425761078">"Se borrarán todos los archivos almacenados en el almacenamiento USB. Esta acción no se puede deshacer."</string>
<string name="extmedia_format_message" product="default" msgid="14131895027543830">"Se perderán todos los datos de tu tarjeta."</string>
<string name="extmedia_format_button_format" msgid="4131064560127478695">"Formato"</string>
- <string name="adb_active_notification_title" msgid="6729044778949189918">"Dispositivo de depuración USB conectado"</string>
- <string name="adb_active_notification_message" msgid="1016654627626476142">"Tocar para inhabilitar la depuración USB"</string>
- <string name="select_input_method" msgid="4653387336791222978">"Seleccionar método de introducción"</string>
- <string name="configure_input_methods" msgid="9091652157722495116">"Ajustar métodos de introducción"</string>
+ <string name="adb_active_notification_title" msgid="6729044778949189918">"Depuración USB habilitada"</string>
+ <string name="adb_active_notification_message" msgid="1016654627626476142">"Toca para inhabilitar la depuración USB"</string>
+ <string name="select_input_method" msgid="4653387336791222978">"Selecciona un método de introducción"</string>
+ <string name="configure_input_methods" msgid="9091652157722495116">"Configurar métodos de introducción"</string>
<string name="use_physical_keyboard" msgid="6203112478095117625">"Teclado físico"</string>
<string name="hardware" msgid="7517821086888990278">"Hardware"</string>
+ <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"Selecciona un diseño de teclado"</string>
+ <string name="select_keyboard_layout_notification_message" msgid="4465907700449257063">"Toca para seleccionar un diseño de teclado."</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>"candidatos"</u></string>
@@ -1303,7 +1310,7 @@
<string name="fingerprints" msgid="4516019619850763049">"Huellas digitales:"</string>
<string name="sha256_fingerprint" msgid="4391271286477279263">"Huella digital SHA-256:"</string>
<string name="sha1_fingerprint" msgid="7930330235269404581">"Huella digital SHA-1:"</string>
- <string name="activity_chooser_view_see_all" msgid="4292569383976636200">"Ver todas"</string>
+ <string name="activity_chooser_view_see_all" msgid="4292569383976636200">"Ver todo"</string>
<string name="activity_chooser_view_dialog_title_default" msgid="4710013864974040615">"Seleccionar actividad"</string>
<string name="share_action_provider_share_with" msgid="5247684435979149216">"Compartir con"</string>
<string name="status_bar_device_locked" msgid="3092703448690669768">"Dispositivo bloqueado"</string>
@@ -1312,5 +1319,5 @@
<string name="launchBrowserDefault" msgid="2057951947297614725">"¿Iniciar el navegador?"</string>
<string name="SetupCallDefault" msgid="5834948469253758575">"¿Aceptar la llamada?"</string>
<string name="activity_resolver_use_always" msgid="8017770747801494933">"Siempre"</string>
- <string name="activity_resolver_use_once" msgid="405646673463328329">"Solo una vez"</string>
+ <string name="activity_resolver_use_once" msgid="2404644797149173758">"Solo una vez"</string>
</resources>
diff --git a/core/res/res/values-et/strings.xml b/core/res/res/values-et/strings.xml
index 88f8fdb..af4b160 100644
--- a/core/res/res/values-et/strings.xml
+++ b/core/res/res/values-et/strings.xml
@@ -317,6 +317,8 @@
<string name="permdesc_readInputState" msgid="8387754901688728043">"Võimaldab rakendusel vaadata vajutatavaid klahve, isegi kui suhtlete teise rakendusega (näiteks parooli sisestamisel). Tavarakenduste puhul ei peaks seda kunagi vaja minema."</string>
<string name="permlab_bindInputMethod" msgid="3360064620230515776">"seo sisestusmeetodiga"</string>
<string name="permdesc_bindInputMethod" msgid="3250440322807286331">"Lubab omanikul siduda sisestusmeetodi ülataseme liidesega. Tavarakenduste puhul ei peaks seda kunagi vaja minema."</string>
+ <string name="permlab_bindAccessibilityService" msgid="5357733942556031593">"sidumine juurdepääsuteenusega"</string>
+ <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Lubab omanikul luua sideme juurdepääsuteenuse ülataseme liidesega. Tavarakenduste puhul ei tohiks seda kunagi vaja minna."</string>
<string name="permlab_bindTextService" msgid="7358378401915287938">"tekstiteenusega sidumine"</string>
<string name="permdesc_bindTextService" msgid="8151968910973998670">"Võimaldab omanikul siduda tekstiteenuse (nt SpellCheckerService) ülataseme liidesega. Tavarakenduste puhul ei peaks seda kunagi vaja minema."</string>
<string name="permlab_bindVpnService" msgid="4708596021161473255">"seo VPN-teenusega"</string>
@@ -853,6 +855,9 @@
<string name="searchview_description_clear" msgid="1330281990951833033">"Tühjenda päring"</string>
<string name="searchview_description_submit" msgid="2688450133297983542">"Päringu esitamine"</string>
<string name="searchview_description_voice" msgid="2453203695674994440">"Häälotsing"</string>
+ <string name="enable_explore_by_touch_warning_title" msgid="7460694070309730149">"Kas lubada puudutusega uurimine?"</string>
+ <string name="enable_explore_by_touch_warning_message" product="tablet" msgid="8655887539089910577">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> soovib lubada puudutusega uurimise. Kui puudutusega uurimine on sisse lülitatud, kuulete või näete kirjeldusi asjade kohta, mis on teie sõrme all, või saate suhelda tahvelarvutiga liigutuste abil."</string>
+ <string name="enable_explore_by_touch_warning_message" product="default" msgid="2708199672852373195">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> soovib lubada puudutusega uurimise. Kui puudutusega uurimine on sisse lülitatud, kuulete või näete kirjeldusi asjade kohta, mis on teie sõrme all, või saate suhelda telefoniga liigutuste abil."</string>
<string name="oneMonthDurationPast" msgid="7396384508953779925">"1 kuu tagasi"</string>
<string name="beforeOneMonthDurationPast" msgid="909134546836499826">"Varem kui 1 kuu tagasi"</string>
<plurals name="num_seconds_ago">
@@ -1119,6 +1124,8 @@
<string name="configure_input_methods" msgid="9091652157722495116">"Seadista sisestusmeetodid"</string>
<string name="use_physical_keyboard" msgid="6203112478095117625">"Füüsiline klaviatuur"</string>
<string name="hardware" msgid="7517821086888990278">"Riistvara"</string>
+ <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"Klaviatuuri paigutuse valimine"</string>
+ <string name="select_keyboard_layout_notification_message" msgid="4465907700449257063">"Puudutage klaviatuuri paigutuse valimiseks."</string>
<string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSŠZŽTUVWÕÄÖÜXY"</string>
<string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSŠZŽTUVWÕÄÖÜXY"</string>
<string name="candidates_style" msgid="4333913089637062257"><u>"kandidaadid"</u></string>
@@ -1312,5 +1319,5 @@
<string name="launchBrowserDefault" msgid="2057951947297614725">"Kas käivitada brauser?"</string>
<string name="SetupCallDefault" msgid="5834948469253758575">"Kas vastata kõnele?"</string>
<string name="activity_resolver_use_always" msgid="8017770747801494933">"Alati"</string>
- <string name="activity_resolver_use_once" msgid="405646673463328329">"Ainult üks kord"</string>
+ <string name="activity_resolver_use_once" msgid="2404644797149173758">"Ainult üks kord"</string>
</resources>
diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml
index 26b5e77..cb83ba3 100644
--- a/core/res/res/values-fa/strings.xml
+++ b/core/res/res/values-fa/strings.xml
@@ -317,6 +317,8 @@
<string name="permdesc_readInputState" msgid="8387754901688728043">"به برنامه اجازه می‎دهد تا کلیدهایی را که هنگام تعامل با برنامه دیگر فشار می‎دهید ببیند (مانند تایپ کردن گذرواژه). برای برنامه‎های عادی مورد نیاز نیست."</string>
<string name="permlab_bindInputMethod" msgid="3360064620230515776">"پیوند شده به روش ورودی"</string>
<string name="permdesc_bindInputMethod" msgid="3250440322807286331">"به دارنده این دستگاه اجازه می‎دهد تا به رابط سطح بالای یک روش ورودی متصل شود. این ویژگی هیچگاه برای برنامه‎های معمولی ضروری نمی‎باشد."</string>
+ <string name="permlab_bindAccessibilityService" msgid="5357733942556031593">"اتصال به سرویس دسترسی"</string>
+ <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"به دارنده اجازه می‌دهد که به رابط سطح بالای سرویس دسترسی متصل شود. هرگز برای برنامه‌های معمولی مورد نیاز نیست."</string>
<string name="permlab_bindTextService" msgid="7358378401915287938">"اتصال به یک سرویس متنی"</string>
<string name="permdesc_bindTextService" msgid="8151968910973998670">"به دارنده اجازه می‌دهد خود را به یک رابط سطح بالای خدمات متنی مرتبط کند (برای مثال SpellCheckerService). هرگز برای برنامه‌های عادی لازم نیست."</string>
<string name="permlab_bindVpnService" msgid="4708596021161473255">"اتصال به یک سرویس VPN"</string>
@@ -853,6 +855,9 @@
<string name="searchview_description_clear" msgid="1330281990951833033">"پاک کردن عبارت جستجو"</string>
<string name="searchview_description_submit" msgid="2688450133297983542">"ارسال عبارت جستجو"</string>
<string name="searchview_description_voice" msgid="2453203695674994440">"جستجوی صوتی"</string>
+ <string name="enable_explore_by_touch_warning_title" msgid="7460694070309730149">"فعال کردن «کاوش با لمس»؟"</string>
+ <string name="enable_explore_by_touch_warning_message" product="tablet" msgid="8655887539089910577">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> می‌خواهد «کاوش با لمس» را فعال کند. وقتی «کاوش با لمس» فعال است، می‌توانید توضیحاتی را برای آنچه که زیر انگشت شما است مشاهده کرده یا بشنوید یا برای استفاده از رایانه لوحی از حرکات اشاره استفاده کنید."</string>
+ <string name="enable_explore_by_touch_warning_message" product="default" msgid="2708199672852373195">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> می‌خواهد «کاوش با لمس» را فعال کند. وقتی «کاوش با لمس» فعال است، می‌توانید توضیحاتی را برای آنچه که زیر انگشت شما است مشاهده کرده یا بشنوید یا برای استفاده از تلفن خود از حرکات اشاره استفاده کنید."</string>
<string name="oneMonthDurationPast" msgid="7396384508953779925">"1 ماه قبل"</string>
<string name="beforeOneMonthDurationPast" msgid="909134546836499826">"قبل از 1 ماه گذشته"</string>
<plurals name="num_seconds_ago">
@@ -1119,6 +1124,8 @@
<string name="configure_input_methods" msgid="9091652157722495116">"تنظیم روش‌های ورودی"</string>
<string name="use_physical_keyboard" msgid="6203112478095117625">"صفحه کلید فیزیکی"</string>
<string name="hardware" msgid="7517821086888990278">"سخت‌افزار"</string>
+ <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"انتخاب طرح‌بندی صفحه کلید"</string>
+ <string name="select_keyboard_layout_notification_message" msgid="4465907700449257063">"برای انتخاب یک طرح‌بندی صفحه کلید لمس کنید…"</string>
<string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="candidates_style" msgid="4333913089637062257"><u>"داوطلبین"</u></string>
@@ -1312,5 +1319,5 @@
<string name="launchBrowserDefault" msgid="2057951947297614725">"مرورگر راه‌اندازی شود؟"</string>
<string name="SetupCallDefault" msgid="5834948469253758575">"تماس را می‌پذیرید؟"</string>
<string name="activity_resolver_use_always" msgid="8017770747801494933">"همیشه"</string>
- <string name="activity_resolver_use_once" msgid="405646673463328329">"فقط یکبار"</string>
+ <string name="activity_resolver_use_once" msgid="2404644797149173758">"فقط یک بار"</string>
</resources>
diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml
index 3d6d5b0..9e0e8e6 100644
--- a/core/res/res/values-fi/strings.xml
+++ b/core/res/res/values-fi/strings.xml
@@ -317,6 +317,8 @@
<string name="permdesc_readInputState" msgid="8387754901688728043">"Antaa sovelluksen lukea näppäinpainalluksia myös käytettäessä muita sovelluksia (esimerkiksi kirjoitettaessa salasanaa). Ei tavallisten sovellusten käyttöön."</string>
<string name="permlab_bindInputMethod" msgid="3360064620230515776">"sitoudu syöttötapaan"</string>
<string name="permdesc_bindInputMethod" msgid="3250440322807286331">"Antaa sovelluksen sitoutua syötetavan ylätason käyttöliittymään. Ei tavallisten sovellusten käyttöön."</string>
+ <string name="permlab_bindAccessibilityService" msgid="5357733942556031593">"sitoudu esteettömyyspalveluun"</string>
+ <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Antaa sovelluksen sitoutua esteettömyyspalvelun ylemmän tason käyttöliittymään. Ei tavallisten sovelluksien käyttöön."</string>
<string name="permlab_bindTextService" msgid="7358378401915287938">"tekstipalveluun sitoutuminen"</string>
<string name="permdesc_bindTextService" msgid="8151968910973998670">"Antaa sovelluksen sitoutua tekstipalvelun (kuten SpellCheckerServicen) ylätason liittymään. Ei tavallisten sovellusten käyttöön."</string>
<string name="permlab_bindVpnService" msgid="4708596021161473255">"sitoudu VPN-palveluun"</string>
@@ -853,6 +855,12 @@
<string name="searchview_description_clear" msgid="1330281990951833033">"Tyhjennä kysely"</string>
<string name="searchview_description_submit" msgid="2688450133297983542">"Lähetä kysely"</string>
<string name="searchview_description_voice" msgid="2453203695674994440">"Puhehaku"</string>
+ <!-- no translation found for enable_explore_by_touch_warning_title (7460694070309730149) -->
+ <skip />
+ <!-- no translation found for enable_explore_by_touch_warning_message (8655887539089910577) -->
+ <skip />
+ <!-- no translation found for enable_explore_by_touch_warning_message (2708199672852373195) -->
+ <skip />
<string name="oneMonthDurationPast" msgid="7396384508953779925">"kuukausi sitten"</string>
<string name="beforeOneMonthDurationPast" msgid="909134546836499826">"Yli kuukausi sitten"</string>
<plurals name="num_seconds_ago">
@@ -1119,6 +1127,10 @@
<string name="configure_input_methods" msgid="9091652157722495116">"Määritä syöttötavat"</string>
<string name="use_physical_keyboard" msgid="6203112478095117625">"Fyysinen näppäimistö"</string>
<string name="hardware" msgid="7517821086888990278">"Laitteisto"</string>
+ <!-- no translation found for select_keyboard_layout_notification_title (1407367017263030773) -->
+ <skip />
+ <!-- no translation found for select_keyboard_layout_notification_message (4465907700449257063) -->
+ <skip />
<string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZÅÄÖ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="candidates_style" msgid="4333913089637062257"><u>"kandidaatit"</u></string>
@@ -1312,5 +1324,6 @@
<string name="launchBrowserDefault" msgid="2057951947297614725">"Käynnistetäänkö selain?"</string>
<string name="SetupCallDefault" msgid="5834948469253758575">"Vastataanko puheluun?"</string>
<string name="activity_resolver_use_always" msgid="8017770747801494933">"Aina"</string>
- <string name="activity_resolver_use_once" msgid="405646673463328329">"Vain kerran"</string>
+ <!-- no translation found for activity_resolver_use_once (2404644797149173758) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml
index 9a8778e..f757e27 100644
--- a/core/res/res/values-fr/strings.xml
+++ b/core/res/res/values-fr/strings.xml
@@ -145,7 +145,7 @@
<string name="shutdown_progress" msgid="2281079257329981203">"Arrêt en cours..."</string>
<string name="shutdown_confirm" product="tablet" msgid="3385745179555731470">"Votre tablette va s\'éteindre."</string>
<string name="shutdown_confirm" product="default" msgid="649792175242821353">"Votre téléphone va s\'éteindre."</string>
- <string name="shutdown_confirm_question" msgid="2906544768881136183">"Voulez-vous éteindre le téléphone ?"</string>
+ <string name="shutdown_confirm_question" msgid="2906544768881136183">"Voulez-vous éteindre l\'appareil ?"</string>
<string name="reboot_safemode_title" msgid="7054509914500140361">"Redémarrer en mode sans échec"</string>
<string name="reboot_safemode_confirm" msgid="55293944502784668">"Voulez-vous redémarrer en mode sans échec ? Cette opération aura pour effet de désactiver toutes les applications tierces que vous avez installées. Elles seront réactivées au prochain redémarrage."</string>
<string name="recent_tasks_title" msgid="3691764623638127888">"Récentes"</string>
@@ -317,6 +317,8 @@
<string name="permdesc_readInputState" msgid="8387754901688728043">"Permet à l\'application d\'identifier les touches sur lesquelles vous appuyez, même lorsque vous utilisez une autre application (lors de la saisie d\'un mot de passe, par exemple). Les applications standards ne devraient jamais avoir recours à cette fonctionnalité."</string>
<string name="permlab_bindInputMethod" msgid="3360064620230515776">"Association à un mode de saisie"</string>
<string name="permdesc_bindInputMethod" msgid="3250440322807286331">"Permet à l\'application autorisée de s\'associer à l\'interface de plus haut niveau d\'un mode de saisie. Les applications standards ne doivent jamais avoir recours à cette fonctionnalité."</string>
+ <string name="permlab_bindAccessibilityService" msgid="5357733942556031593">"associer à un service d\'accessibilité"</string>
+ <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Permet à l\'application autorisée de s\'associer à l\'interface de plus haut niveau d\'un service d\'accessibilité. Les applications standards ne doivent jamais avoir recours à cette fonctionnalité."</string>
<string name="permlab_bindTextService" msgid="7358378401915287938">"associer à un service de texte"</string>
<string name="permdesc_bindTextService" msgid="8151968910973998670">"Permet à l\'application de s\'associer à l\'interface de haut niveau d\'un service de texte (par exemple, SpellCheckerService). Les applications standards ne doivent jamais avoir recours à cette fonctionnalité."</string>
<string name="permlab_bindVpnService" msgid="4708596021161473255">"associer à un service VPN"</string>
@@ -853,6 +855,12 @@
<string name="searchview_description_clear" msgid="1330281990951833033">"Effacer la requête"</string>
<string name="searchview_description_submit" msgid="2688450133297983542">"Envoyer la requête"</string>
<string name="searchview_description_voice" msgid="2453203695674994440">"Recherche vocale"</string>
+ <!-- no translation found for enable_explore_by_touch_warning_title (7460694070309730149) -->
+ <skip />
+ <!-- no translation found for enable_explore_by_touch_warning_message (8655887539089910577) -->
+ <skip />
+ <!-- no translation found for enable_explore_by_touch_warning_message (2708199672852373195) -->
+ <skip />
<string name="oneMonthDurationPast" msgid="7396384508953779925">"Il y a 1 mois"</string>
<string name="beforeOneMonthDurationPast" msgid="909134546836499826">"Il y a plus d\'un mois"</string>
<plurals name="num_seconds_ago">
@@ -1119,6 +1127,10 @@
<string name="configure_input_methods" msgid="9091652157722495116">"Configurer les modes de saisie"</string>
<string name="use_physical_keyboard" msgid="6203112478095117625">"Clavier physique"</string>
<string name="hardware" msgid="7517821086888990278">"Matériel"</string>
+ <!-- no translation found for select_keyboard_layout_notification_title (1407367017263030773) -->
+ <skip />
+ <!-- no translation found for select_keyboard_layout_notification_message (4465907700449257063) -->
+ <skip />
<string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="candidates_style" msgid="4333913089637062257"><u>"candidats"</u></string>
@@ -1312,5 +1324,6 @@
<string name="launchBrowserDefault" msgid="2057951947297614725">"Lancer le navigateur ?"</string>
<string name="SetupCallDefault" msgid="5834948469253758575">"Prendre l\'appel ?"</string>
<string name="activity_resolver_use_always" msgid="8017770747801494933">"Toujours"</string>
- <string name="activity_resolver_use_once" msgid="405646673463328329">"Une seule fois"</string>
+ <!-- no translation found for activity_resolver_use_once (2404644797149173758) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml
index 008f93b..47656b6 100644
--- a/core/res/res/values-hi/strings.xml
+++ b/core/res/res/values-hi/strings.xml
@@ -317,6 +317,8 @@
<string name="permdesc_readInputState" msgid="8387754901688728043">"एप्लिकेशन को अन्य एप्लिकेशन के साथ सहभागिता करते समय भी आपके द्वारा दबाई जाने वाली कुंजियां देखने देता है (जैसे कोई पासवर्ड लिखना). सामान्‍य एप्‍लिकेशन के लिए कभी भी आवश्‍यक नहीं होना चाहिए."</string>
<string name="permlab_bindInputMethod" msgid="3360064620230515776">"किसी इनपुट विधि से आबद्ध करें"</string>
<string name="permdesc_bindInputMethod" msgid="3250440322807286331">"धारक को किसी इनपुट विधि के शीर्ष-स्‍तर इंटरफ़ेस से आबद्ध होने देता है. सामान्‍य एप्‍लिकेशन के लिए कभी भी आवश्‍यक नहीं होना चाहिए."</string>
+ <string name="permlab_bindAccessibilityService" msgid="5357733942556031593">"पहुंच-योग्‍यता सेवा से आबद्ध करें"</string>
+ <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"धारक को किसी पहुंच-योग्यता सेवा के शीर्ष-स्‍तर इंटरफ़ेस से आबद्ध होने देता है. सामान्‍य एप्‍लिकेशन के लिए कभी भी आवश्‍यक नहीं होना चाहिए."</string>
<string name="permlab_bindTextService" msgid="7358378401915287938">"किसी पाठ सेवा पर बने रहें"</string>
<string name="permdesc_bindTextService" msgid="8151968910973998670">"धारक को किसी पाठ सेवा (उदा. SpellCheckerService) के शीर्ष-स्‍तर इंटरफ़ेस पर आबद्ध होने देता है. सामान्‍य एप्‍लिकेशन के लिए कभी भी आवश्‍यक नहीं होना चाहिए."</string>
<string name="permlab_bindVpnService" msgid="4708596021161473255">"किसी VPN सेवा से आबद्ध करें"</string>
@@ -853,6 +855,12 @@
<string name="searchview_description_clear" msgid="1330281990951833033">"क्‍वेरी साफ़ करें"</string>
<string name="searchview_description_submit" msgid="2688450133297983542">"क्वेरी सबमिट करें"</string>
<string name="searchview_description_voice" msgid="2453203695674994440">"ध्वनि खोज"</string>
+ <!-- no translation found for enable_explore_by_touch_warning_title (7460694070309730149) -->
+ <skip />
+ <!-- no translation found for enable_explore_by_touch_warning_message (8655887539089910577) -->
+ <skip />
+ <!-- no translation found for enable_explore_by_touch_warning_message (2708199672852373195) -->
+ <skip />
<string name="oneMonthDurationPast" msgid="7396384508953779925">"1 माह पहले"</string>
<string name="beforeOneMonthDurationPast" msgid="909134546836499826">"1 माह से पहले"</string>
<plurals name="num_seconds_ago">
@@ -1119,6 +1127,10 @@
<string name="configure_input_methods" msgid="9091652157722495116">"इनपुट पद्धतियां सेट करें"</string>
<string name="use_physical_keyboard" msgid="6203112478095117625">"भौतिक कीबोर्ड"</string>
<string name="hardware" msgid="7517821086888990278">"हार्डवेयर"</string>
+ <!-- no translation found for select_keyboard_layout_notification_title (1407367017263030773) -->
+ <skip />
+ <!-- no translation found for select_keyboard_layout_notification_message (4465907700449257063) -->
+ <skip />
<string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="candidates_style" msgid="4333913089637062257"><u>"उम्‍मीदवार"</u></string>
@@ -1312,5 +1324,6 @@
<string name="launchBrowserDefault" msgid="2057951947297614725">"ब्राउज़र लॉन्च करें?"</string>
<string name="SetupCallDefault" msgid="5834948469253758575">"कॉल स्वीकार करें?"</string>
<string name="activity_resolver_use_always" msgid="8017770747801494933">"हमेशा"</string>
- <string name="activity_resolver_use_once" msgid="405646673463328329">"बस एक बार"</string>
+ <!-- no translation found for activity_resolver_use_once (2404644797149173758) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml
index 55f923f..98f736b 100644
--- a/core/res/res/values-hr/strings.xml
+++ b/core/res/res/values-hr/strings.xml
@@ -317,6 +317,8 @@
<string name="permdesc_readInputState" msgid="8387754901688728043">"Omogućuje aplikaciji da gleda koje tipke pritiskate čak i kada radite s nekom drugom aplikacijom (na primjer, pisanje zaporke). Ne bi smjelo biti potrebno za normalne aplikacije."</string>
<string name="permlab_bindInputMethod" msgid="3360064620230515776">"vezano uz način unosa"</string>
<string name="permdesc_bindInputMethod" msgid="3250440322807286331">"Nositelju omogućuje povezivanje sučelja najviše razine načina unosa. Ne bi smjelo biti potrebno za normalne aplikacije."</string>
+ <string name="permlab_bindAccessibilityService" msgid="5357733942556031593">"vezivanje uz uslugu dostupnosti"</string>
+ <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Nositelju omogućuje vezanje uz sučelje najviše razine usluge dostupnosti. Ne bi smjelo biti potrebno za normalne aplikacije."</string>
<string name="permlab_bindTextService" msgid="7358378401915287938">"vezanje na tekstualnu uslugu"</string>
<string name="permdesc_bindTextService" msgid="8151968910973998670">"Omogućuje korisniku povezivanje s najvišom razinom sučelja tekstualne usluge (npr. SpellCheckerService). Ne bi smjelo biti potrebno za normalne aplikacije."</string>
<string name="permlab_bindVpnService" msgid="4708596021161473255">"vezanje na VPN uslugu"</string>
@@ -853,6 +855,12 @@
<string name="searchview_description_clear" msgid="1330281990951833033">"Izbriši upit"</string>
<string name="searchview_description_submit" msgid="2688450133297983542">"Pošalji upit"</string>
<string name="searchview_description_voice" msgid="2453203695674994440">"Glasovno pretraživanje"</string>
+ <!-- no translation found for enable_explore_by_touch_warning_title (7460694070309730149) -->
+ <skip />
+ <!-- no translation found for enable_explore_by_touch_warning_message (8655887539089910577) -->
+ <skip />
+ <!-- no translation found for enable_explore_by_touch_warning_message (2708199672852373195) -->
+ <skip />
<string name="oneMonthDurationPast" msgid="7396384508953779925">"Prije 1 mjesec"</string>
<string name="beforeOneMonthDurationPast" msgid="909134546836499826">"Prije 1 mjesec"</string>
<plurals name="num_seconds_ago">
@@ -1119,6 +1127,10 @@
<string name="configure_input_methods" msgid="9091652157722495116">"Postavljanje načina unosa"</string>
<string name="use_physical_keyboard" msgid="6203112478095117625">"Fizička tipkovnica"</string>
<string name="hardware" msgid="7517821086888990278">"Hardver"</string>
+ <!-- no translation found for select_keyboard_layout_notification_title (1407367017263030773) -->
+ <skip />
+ <!-- no translation found for select_keyboard_layout_notification_message (4465907700449257063) -->
+ <skip />
<string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="candidates_style" msgid="4333913089637062257"><u>"kandidati"</u></string>
@@ -1312,5 +1324,6 @@
<string name="launchBrowserDefault" msgid="2057951947297614725">"Pokrenuti preglednik?"</string>
<string name="SetupCallDefault" msgid="5834948469253758575">"Prihvatiti poziv?"</string>
<string name="activity_resolver_use_always" msgid="8017770747801494933">"Uvijek"</string>
- <string name="activity_resolver_use_once" msgid="405646673463328329">"Samo jednom"</string>
+ <!-- no translation found for activity_resolver_use_once (2404644797149173758) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml
index 04ea787..239bfe4 100644
--- a/core/res/res/values-hu/strings.xml
+++ b/core/res/res/values-hu/strings.xml
@@ -317,6 +317,8 @@
<string name="permdesc_readInputState" msgid="8387754901688728043">"Lehetővé teszi az alkalmazás számára, hogy figyelje a lenyomott billentyűket még másik alkalmazás használata esetén is (például jelszó beírásakor). A normál alkalmazásoknak erre soha nincs szüksége."</string>
<string name="permlab_bindInputMethod" msgid="3360064620230515776">"összekapcsolás egy beviteli módszerrel"</string>
<string name="permdesc_bindInputMethod" msgid="3250440322807286331">"Lehetővé teszi, hogy a tulajdonos kötelezővé tegye egy beviteli mód legfelső szintű felületét. A normál alkalmazásoknak erre soha nincs szüksége."</string>
+ <string name="permlab_bindAccessibilityService" msgid="5357733942556031593">"csatlakozás egy kisegítő szolgáltatáshoz"</string>
+ <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Lehetővé teszi a használó számára, hogy csatlakozzon egy kisegítő szolgáltatás legfelső szintű kezelőfelületéhez. A normál alkalmazásoknak erre soha nincs szükségük."</string>
<string name="permlab_bindTextService" msgid="7358378401915287938">"csatlakozás szövegszolgáltatáshoz"</string>
<string name="permdesc_bindTextService" msgid="8151968910973998670">"Lehetővé teszi, hogy a tulajdonos egy szöveges szolgáltatás felső szintjéhez kapcsolódjon (pl. SpellCheckerService). A normál alkalmazásoknak erre soha nincs szüksége."</string>
<string name="permlab_bindVpnService" msgid="4708596021161473255">"csatlakozás egy VPN-szolgáltatáshoz"</string>
@@ -853,6 +855,12 @@
<string name="searchview_description_clear" msgid="1330281990951833033">"Lekérdezés törlése"</string>
<string name="searchview_description_submit" msgid="2688450133297983542">"Lekérdezés küldése"</string>
<string name="searchview_description_voice" msgid="2453203695674994440">"Hangalapú keresés"</string>
+ <!-- no translation found for enable_explore_by_touch_warning_title (7460694070309730149) -->
+ <skip />
+ <!-- no translation found for enable_explore_by_touch_warning_message (8655887539089910577) -->
+ <skip />
+ <!-- no translation found for enable_explore_by_touch_warning_message (2708199672852373195) -->
+ <skip />
<string name="oneMonthDurationPast" msgid="7396384508953779925">"1 hónapja"</string>
<string name="beforeOneMonthDurationPast" msgid="909134546836499826">"Több mint 1 hónapja"</string>
<plurals name="num_seconds_ago">
@@ -1119,6 +1127,10 @@
<string name="configure_input_methods" msgid="9091652157722495116">"Beviteli módok beállítása"</string>
<string name="use_physical_keyboard" msgid="6203112478095117625">"Fizikai billentyűzet"</string>
<string name="hardware" msgid="7517821086888990278">"Hardver"</string>
+ <!-- no translation found for select_keyboard_layout_notification_title (1407367017263030773) -->
+ <skip />
+ <!-- no translation found for select_keyboard_layout_notification_message (4465907700449257063) -->
+ <skip />
<string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="candidates_style" msgid="4333913089637062257"><u>"jelöltek"</u></string>
@@ -1312,5 +1324,6 @@
<string name="launchBrowserDefault" msgid="2057951947297614725">"Böngésző indítása?"</string>
<string name="SetupCallDefault" msgid="5834948469253758575">"Fogadja a hívást?"</string>
<string name="activity_resolver_use_always" msgid="8017770747801494933">"Mindig"</string>
- <string name="activity_resolver_use_once" msgid="405646673463328329">"Csak egyszer"</string>
+ <!-- no translation found for activity_resolver_use_once (2404644797149173758) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml
index 5bca912..b2879e9 100644
--- a/core/res/res/values-in/strings.xml
+++ b/core/res/res/values-in/strings.xml
@@ -317,6 +317,8 @@
<string name="permdesc_readInputState" msgid="8387754901688728043">"Mengizinkan apl mengawasi tombol yang Anda tekan bahkan ketika berinteraksi dengan apl lain (misalnya mengetik sandi). Tidak pernah diperlukan oleh apl normal."</string>
<string name="permlab_bindInputMethod" msgid="3360064620230515776">"mengikat ke metode masukan"</string>
<string name="permdesc_bindInputMethod" msgid="3250440322807286331">"Mengizinkan pemegang mengikat antarmuka tingkat tinggi dari suatu metode masukan. Tidak pernah diperlukan oleh apl normal."</string>
+ <string name="permlab_bindAccessibilityService" msgid="5357733942556031593">"mengikat ke layanan aksesibilitas"</string>
+ <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Mengizinkan pemegang untuk mengikat antarmuka tingkat tinggi dari suatu layanan. Tidak pernah diperlukan oleh aplikasi normal."</string>
<string name="permlab_bindTextService" msgid="7358378401915287938">"mengikat ke layanan SMS"</string>
<string name="permdesc_bindTextService" msgid="8151968910973998670">"Mengizinkan pemegang mengikat antarmuka tingkat tinggi dari suatu layanan teks (mis. SpellCheckerService). Tidak pernah diperlukan oleh apl normal."</string>
<string name="permlab_bindVpnService" msgid="4708596021161473255">"mengikat ke layanan VPN"</string>
@@ -604,30 +606,30 @@
<item msgid="1735177144948329370">"Faks Rumah"</item>
<item msgid="603878674477207394">"Pager"</item>
<item msgid="1650824275177931637">"Lainnya"</item>
- <item msgid="9192514806975898961">"Ubahsuaian"</item>
+ <item msgid="9192514806975898961">"Khusus"</item>
</string-array>
<string-array name="emailAddressTypes">
<item msgid="8073994352956129127">"Rumah"</item>
<item msgid="7084237356602625604">"Kantor"</item>
<item msgid="1112044410659011023">"Lainnya"</item>
- <item msgid="2374913952870110618">"Ubahsuaian"</item>
+ <item msgid="2374913952870110618">"Khusus"</item>
</string-array>
<string-array name="postalAddressTypes">
<item msgid="6880257626740047286">"Rumah"</item>
<item msgid="5629153956045109251">"Kantor"</item>
<item msgid="4966604264500343469">"Lainnya"</item>
- <item msgid="4932682847595299369">"Ubahsuaian"</item>
+ <item msgid="4932682847595299369">"Khusus"</item>
</string-array>
<string-array name="imAddressTypes">
<item msgid="1738585194601476694">"Rumah"</item>
<item msgid="1359644565647383708">"Kantor"</item>
<item msgid="7868549401053615677">"Lainnya"</item>
- <item msgid="3145118944639869809">"Ubahsuaian"</item>
+ <item msgid="3145118944639869809">"Khusus"</item>
</string-array>
<string-array name="organizationTypes">
<item msgid="7546335612189115615">"Kantor"</item>
<item msgid="4378074129049520373">"Lainnya"</item>
- <item msgid="3455047468583965104">"Ubahsuaian"</item>
+ <item msgid="3455047468583965104">"Khusus"</item>
</string-array>
<string-array name="imProtocols">
<item msgid="8595261363518459565">"AIM"</item>
@@ -639,7 +641,7 @@
<item msgid="2506857312718630823">"ICQ"</item>
<item msgid="1648797903785279353">"Jabber"</item>
</string-array>
- <string name="phoneTypeCustom" msgid="1644738059053355820">"Ubahsuaian"</string>
+ <string name="phoneTypeCustom" msgid="1644738059053355820">"Khusus"</string>
<string name="phoneTypeHome" msgid="2570923463033985887">"Rumah"</string>
<string name="phoneTypeMobile" msgid="6501463557754751037">"Seluler"</string>
<string name="phoneTypeWork" msgid="8863939667059911633">"Kantor"</string>
@@ -660,24 +662,24 @@
<string name="phoneTypeWorkPager" msgid="649938731231157056">"Pager Kantor"</string>
<string name="phoneTypeAssistant" msgid="5596772636128562884">"Asisten"</string>
<string name="phoneTypeMms" msgid="7254492275502768992">"MMS"</string>
- <string name="eventTypeCustom" msgid="7837586198458073404">"Ubahsuaian"</string>
+ <string name="eventTypeCustom" msgid="7837586198458073404">"Khusus"</string>
<string name="eventTypeBirthday" msgid="2813379844211390740">"Hari Ulang Tahun"</string>
<string name="eventTypeAnniversary" msgid="3876779744518284000">"Hari Peringatan"</string>
<string name="eventTypeOther" msgid="7388178939010143077">"Lainnya"</string>
- <string name="emailTypeCustom" msgid="8525960257804213846">"Ubahsuaian"</string>
+ <string name="emailTypeCustom" msgid="8525960257804213846">"Khusus"</string>
<string name="emailTypeHome" msgid="449227236140433919">"Rumah"</string>
<string name="emailTypeWork" msgid="3548058059601149973">"Kantor"</string>
<string name="emailTypeOther" msgid="2923008695272639549">"Lainnya"</string>
<string name="emailTypeMobile" msgid="119919005321166205">"Seluler"</string>
- <string name="postalTypeCustom" msgid="8903206903060479902">"Ubahsuaian"</string>
+ <string name="postalTypeCustom" msgid="8903206903060479902">"Khusus"</string>
<string name="postalTypeHome" msgid="8165756977184483097">"Rumah"</string>
<string name="postalTypeWork" msgid="5268172772387694495">"Kantor"</string>
<string name="postalTypeOther" msgid="2726111966623584341">"Lainnya"</string>
- <string name="imTypeCustom" msgid="2074028755527826046">"Ubahsuaian"</string>
+ <string name="imTypeCustom" msgid="2074028755527826046">"Khusus"</string>
<string name="imTypeHome" msgid="6241181032954263892">"Rumah"</string>
<string name="imTypeWork" msgid="1371489290242433090">"Kantor"</string>
<string name="imTypeOther" msgid="5377007495735915478">"Lainnya"</string>
- <string name="imProtocolCustom" msgid="6919453836618749992">"Ubahsuaian"</string>
+ <string name="imProtocolCustom" msgid="6919453836618749992">"Khusus"</string>
<string name="imProtocolAim" msgid="7050360612368383417">"AIM"</string>
<string name="imProtocolMsn" msgid="144556545420769442">"Windows Live"</string>
<string name="imProtocolYahoo" msgid="8271439408469021273">"Yahoo"</string>
@@ -689,8 +691,8 @@
<string name="imProtocolNetMeeting" msgid="8287625655986827971">"NetMeeting"</string>
<string name="orgTypeWork" msgid="29268870505363872">"Kantor"</string>
<string name="orgTypeOther" msgid="3951781131570124082">"Lainnya"</string>
- <string name="orgTypeCustom" msgid="225523415372088322">"Ubahsuaian"</string>
- <string name="relationTypeCustom" msgid="3542403679827297300">"Ubahsuaian"</string>
+ <string name="orgTypeCustom" msgid="225523415372088322">"Khusus"</string>
+ <string name="relationTypeCustom" msgid="3542403679827297300">"Khusus"</string>
<string name="relationTypeAssistant" msgid="6274334825195379076">"Asisten"</string>
<string name="relationTypeBrother" msgid="8757913506784067713">"Saudara laki-laki"</string>
<string name="relationTypeChild" msgid="1890746277276881626">"Anak"</string>
@@ -705,7 +707,7 @@
<string name="relationTypeRelative" msgid="1799819930085610271">"Sanak saudara"</string>
<string name="relationTypeSister" msgid="1735983554479076481">"Saudara perempuan"</string>
<string name="relationTypeSpouse" msgid="394136939428698117">"Pasangan"</string>
- <string name="sipAddressTypeCustom" msgid="2473580593111590945">"Ubahsuaian"</string>
+ <string name="sipAddressTypeCustom" msgid="2473580593111590945">"Khusus"</string>
<string name="sipAddressTypeHome" msgid="6093598181069359295">"Beranda"</string>
<string name="sipAddressTypeWork" msgid="6920725730797099047">"Kerjaan"</string>
<string name="sipAddressTypeOther" msgid="4408436162950119849">"Lainnya"</string>
@@ -853,6 +855,9 @@
<string name="searchview_description_clear" msgid="1330281990951833033">"Hapus kueri"</string>
<string name="searchview_description_submit" msgid="2688450133297983542">"Mengirimkan kueri"</string>
<string name="searchview_description_voice" msgid="2453203695674994440">"Penelusuran suara"</string>
+ <string name="enable_explore_by_touch_warning_title" msgid="7460694070309730149">"Aktifkan Menjelajah dengan Sentuhan?"</string>
+ <string name="enable_explore_by_touch_warning_message" product="tablet" msgid="8655887539089910577">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> ingin mengaktifkan Menjelajah dengan Sentuhan. Saat Menjelajah dengan Sentuhan diaktifkan, Anda dapat melihat atau mendengar deskripsi dari apa yang ada di bawah jari Anda atau melakukan gerakan untuk berinteraksi dengan tablet."</string>
+ <string name="enable_explore_by_touch_warning_message" product="default" msgid="2708199672852373195">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> ingin mengaktifkan Menjelajah dengan Sentuhan. Saat Menjelajah dengan Sentuhan diaktifkan, Anda dapat mendengar atau melihat deskripsi dari apa yang ada di bawah jari Anda atau melakukan gerakan untuk berinteraksi dengan ponsel."</string>
<string name="oneMonthDurationPast" msgid="7396384508953779925">"1 bulan yang lalu"</string>
<string name="beforeOneMonthDurationPast" msgid="909134546836499826">"Sebelum 1 bulan yang lalu"</string>
<plurals name="num_seconds_ago">
@@ -1119,6 +1124,8 @@
<string name="configure_input_methods" msgid="9091652157722495116">"Menyiapkan metode masukan"</string>
<string name="use_physical_keyboard" msgid="6203112478095117625">"Keyboard fisik"</string>
<string name="hardware" msgid="7517821086888990278">"Perangkat Keras"</string>
+ <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"Pilih tata letak keyboard"</string>
+ <string name="select_keyboard_layout_notification_message" msgid="4465907700449257063">"Sentuh untuk memilih tata letak keyboard."</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>"calon"</u></string>
@@ -1312,5 +1319,5 @@
<string name="launchBrowserDefault" msgid="2057951947297614725">"Luncurkan Browser?"</string>
<string name="SetupCallDefault" msgid="5834948469253758575">"Terima panggilan?"</string>
<string name="activity_resolver_use_always" msgid="8017770747801494933">"Selalu"</string>
- <string name="activity_resolver_use_once" msgid="405646673463328329">"Sekali Saja"</string>
+ <string name="activity_resolver_use_once" msgid="2404644797149173758">"Hanya sekali"</string>
</resources>
diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml
index 0764284..ffcf6bb 100644
--- a/core/res/res/values-it/strings.xml
+++ b/core/res/res/values-it/strings.xml
@@ -317,6 +317,8 @@
<string name="permdesc_readInputState" msgid="8387754901688728043">"Consente all\'applicazione di conoscere i tasti premuti anche durante l\'interazione con un\'altra applicazione (ad esempio quando digiti una password). Non dovrebbe mai essere necessaria per le applicazioni normali."</string>
<string name="permlab_bindInputMethod" msgid="3360064620230515776">"associaz. a un metodo di inserimento"</string>
<string name="permdesc_bindInputMethod" msgid="3250440322807286331">"Consente l\'associazione di un metodo di inserimento all\'interfaccia principale. Non dovrebbe mai essere necessaria per le normali applicazioni."</string>
+ <string name="permlab_bindAccessibilityService" msgid="5357733942556031593">"collegamento a un servizio di accessibilità"</string>
+ <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Consente al titolare di collegarsi all\'interfaccia di primo livello di un servizio di accessibilità. Non dovrebbe essere mai necessaria per le normali applicazioni."</string>
<string name="permlab_bindTextService" msgid="7358378401915287938">"associazione a un servizio di testo"</string>
<string name="permdesc_bindTextService" msgid="8151968910973998670">"Consente al titolare di collegarsi all\'interfaccia di primo livello di un servizio di testo (ad esempio SpellCheckerService). Non dovrebbe essere mai necessaria per le normali applicazioni."</string>
<string name="permlab_bindVpnService" msgid="4708596021161473255">"associazione a un servizio VPN"</string>
@@ -853,6 +855,12 @@
<string name="searchview_description_clear" msgid="1330281990951833033">"Cancella query"</string>
<string name="searchview_description_submit" msgid="2688450133297983542">"Invia query"</string>
<string name="searchview_description_voice" msgid="2453203695674994440">"Ricerca vocale"</string>
+ <!-- no translation found for enable_explore_by_touch_warning_title (7460694070309730149) -->
+ <skip />
+ <!-- no translation found for enable_explore_by_touch_warning_message (8655887539089910577) -->
+ <skip />
+ <!-- no translation found for enable_explore_by_touch_warning_message (2708199672852373195) -->
+ <skip />
<string name="oneMonthDurationPast" msgid="7396384508953779925">"1 mese fa"</string>
<string name="beforeOneMonthDurationPast" msgid="909134546836499826">"Oltre 1 mese fa"</string>
<plurals name="num_seconds_ago">
@@ -1119,6 +1127,10 @@
<string name="configure_input_methods" msgid="9091652157722495116">"Configura metodi di immissione"</string>
<string name="use_physical_keyboard" msgid="6203112478095117625">"Tastiera fisica"</string>
<string name="hardware" msgid="7517821086888990278">"Hardware"</string>
+ <!-- no translation found for select_keyboard_layout_notification_title (1407367017263030773) -->
+ <skip />
+ <!-- no translation found for select_keyboard_layout_notification_message (4465907700449257063) -->
+ <skip />
<string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="candidates_style" msgid="4333913089637062257"><u>"candidati"</u></string>
@@ -1312,5 +1324,6 @@
<string name="launchBrowserDefault" msgid="2057951947297614725">"Avviare l\'applicazione Browser?"</string>
<string name="SetupCallDefault" msgid="5834948469253758575">"Accettare la chiamata?"</string>
<string name="activity_resolver_use_always" msgid="8017770747801494933">"Sempre"</string>
- <string name="activity_resolver_use_once" msgid="405646673463328329">"Solo una volta"</string>
+ <!-- no translation found for activity_resolver_use_once (2404644797149173758) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml
index a111f5a..265da95 100644
--- a/core/res/res/values-iw/strings.xml
+++ b/core/res/res/values-iw/strings.xml
@@ -317,6 +317,8 @@
<string name="permdesc_readInputState" msgid="8387754901688728043">"מאפשר ליישום לצפות במקשים שאתה לוחץ עליהם בעת ביצוע פעילות עם יישום אחר (למשל, הקלדת סיסמה). הרשאה זו לעולם אינה נחוצה ליישומים רגילים."</string>
<string name="permlab_bindInputMethod" msgid="3360064620230515776">"הכפף לשיטת קלט"</string>
<string name="permdesc_bindInputMethod" msgid="3250440322807286331">"מאפשר למשתמש לבצע איגוד לממשק ברמה עליונה של שיטת קלט. הרשאה זו לעולם אינה נחוצה ליישומים רגילים."</string>
+ <string name="permlab_bindAccessibilityService" msgid="5357733942556031593">"הכפפה לשירות נגישות"</string>
+ <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"מתיר לבעלים להכפיף לממשק ברמה העליונה של שירות זמינות. הרשאה זו אף פעם אינה אמורה להיות נחוצה ליישומים רגילים."</string>
<string name="permlab_bindTextService" msgid="7358378401915287938">"הכפפה לשירות טקסט"</string>
<string name="permdesc_bindTextService" msgid="8151968910973998670">"מאפשר למשתמש ליצור איגוד לממשק הרמה העליונה של שירות טקסט (למשל, SpellCheckerService). הרשאה זו לעולם אינה נחוצה ליישומים רגילים."</string>
<string name="permlab_bindVpnService" msgid="4708596021161473255">"אגד לשירות VPN"</string>
@@ -853,6 +855,9 @@
<string name="searchview_description_clear" msgid="1330281990951833033">"נקה שאילתה"</string>
<string name="searchview_description_submit" msgid="2688450133297983542">"שלח שאילתה"</string>
<string name="searchview_description_voice" msgid="2453203695674994440">"חיפוש קולי"</string>
+ <string name="enable_explore_by_touch_warning_title" msgid="7460694070309730149">"האם להפעיל את התכונה \'חקור על ידי מגע\'?"</string>
+ <string name="enable_explore_by_touch_warning_message" product="tablet" msgid="8655887539089910577">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> רוצה להפעיל את התכונה \'חקור על ידי מגע\'. כאשר התכונה \'חקור על ידי מגע\' מופעלת, אתה יכול לשמוע או לראות תיאורים של הפריטים שעליהם אצבעך מונחת או לקיים אינטראקציה עם הטאבלט באמצעות מחוות."</string>
+ <string name="enable_explore_by_touch_warning_message" product="default" msgid="2708199672852373195">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> רוצה להפעיל את התכונה \'חקור על ידי מגע\'. כאשר התכונה \'חקור על ידי מגע\' מופעלת, אתה יכול לשמוע או לראות תיאורים של הפריטים שעליהם אצבעך מונחת או לקיים אינטראקציה עם הטלפון באמצעות מחוות."</string>
<string name="oneMonthDurationPast" msgid="7396384508953779925">"לפני חודש אחד"</string>
<string name="beforeOneMonthDurationPast" msgid="909134546836499826">"לפני חודש אחד"</string>
<plurals name="num_seconds_ago">
@@ -1119,6 +1124,8 @@
<string name="configure_input_methods" msgid="9091652157722495116">"הגדר שיטות קלט"</string>
<string name="use_physical_keyboard" msgid="6203112478095117625">"מקלדת פיזית"</string>
<string name="hardware" msgid="7517821086888990278">"חומרה"</string>
+ <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"בחירת פריסת מקלדת"</string>
+ <string name="select_keyboard_layout_notification_message" msgid="4465907700449257063">"גע כדי לבחור פריסת מקלדת."</string>
<string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="candidates_style" msgid="4333913089637062257"><u>"מועמדים"</u></string>
@@ -1312,5 +1319,5 @@
<string name="launchBrowserDefault" msgid="2057951947297614725">"להפעיל את הדפדפן?"</string>
<string name="SetupCallDefault" msgid="5834948469253758575">"האם לקבל את השיחה?"</string>
<string name="activity_resolver_use_always" msgid="8017770747801494933">"תמיד"</string>
- <string name="activity_resolver_use_once" msgid="405646673463328329">"רק פעם אחת"</string>
+ <string name="activity_resolver_use_once" msgid="2404644797149173758">"רק פעם אחת"</string>
</resources>
diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml
index 7e3e95b..176a6b5 100644
--- a/core/res/res/values-ja/strings.xml
+++ b/core/res/res/values-ja/strings.xml
@@ -317,6 +317,8 @@
<string name="permdesc_readInputState" msgid="8387754901688728043">"別のアプリとの対話操作(パスワード入力など)の場合でもキー入力を監視することをアプリに許可します。通常のアプリでは不要です。"</string>
<string name="permlab_bindInputMethod" msgid="3360064620230515776">"入力方法に関連付ける"</string>
<string name="permdesc_bindInputMethod" msgid="3250440322807286331">"入力方法のトップレベルインターフェースにバインドすることを所有者に許可します。通常のアプリでは不要です。"</string>
+ <string name="permlab_bindAccessibilityService" msgid="5357733942556031593">"ユーザー補助サービスにバインド"</string>
+ <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"ユーザー補助サービスのトップレベルインターフェースにバインドすることを所有者に許可します。通常のアプリでは不要です。"</string>
<string name="permlab_bindTextService" msgid="7358378401915287938">"テキストサービスにバインド"</string>
<string name="permdesc_bindTextService" msgid="8151968910973998670">"テキストサービス(SpellCheckerServiceなど)のトップレベルインターフェースにバインドすることを所有者に許可します。通常のアプリでは不要です。"</string>
<string name="permlab_bindVpnService" msgid="4708596021161473255">"VPNサービスにバインド"</string>
@@ -853,6 +855,12 @@
<string name="searchview_description_clear" msgid="1330281990951833033">"検索キーワードを削除"</string>
<string name="searchview_description_submit" msgid="2688450133297983542">"検索キーワードを送信"</string>
<string name="searchview_description_voice" msgid="2453203695674994440">"音声検索"</string>
+ <!-- no translation found for enable_explore_by_touch_warning_title (7460694070309730149) -->
+ <skip />
+ <!-- no translation found for enable_explore_by_touch_warning_message (8655887539089910577) -->
+ <skip />
+ <!-- no translation found for enable_explore_by_touch_warning_message (2708199672852373195) -->
+ <skip />
<string name="oneMonthDurationPast" msgid="7396384508953779925">"1か月前"</string>
<string name="beforeOneMonthDurationPast" msgid="909134546836499826">"1か月前"</string>
<plurals name="num_seconds_ago">
@@ -1119,6 +1127,10 @@
<string name="configure_input_methods" msgid="9091652157722495116">"入力方法をセットアップ"</string>
<string name="use_physical_keyboard" msgid="6203112478095117625">"物理キーボード"</string>
<string name="hardware" msgid="7517821086888990278">"ハードウェア"</string>
+ <!-- no translation found for select_keyboard_layout_notification_title (1407367017263030773) -->
+ <skip />
+ <!-- no translation found for select_keyboard_layout_notification_message (4465907700449257063) -->
+ <skip />
<string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="candidates_style" msgid="4333913089637062257"><u>"候補"</u></string>
@@ -1312,5 +1324,6 @@
<string name="launchBrowserDefault" msgid="2057951947297614725">"ブラウザを起動しますか?"</string>
<string name="SetupCallDefault" msgid="5834948469253758575">"通話を受けますか?"</string>
<string name="activity_resolver_use_always" msgid="8017770747801494933">"常時"</string>
- <string name="activity_resolver_use_once" msgid="405646673463328329">"今回のみ"</string>
+ <!-- no translation found for activity_resolver_use_once (2404644797149173758) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml
index 14730d9..4e3fe51 100644
--- a/core/res/res/values-ko/strings.xml
+++ b/core/res/res/values-ko/strings.xml
@@ -317,6 +317,8 @@
<string name="permdesc_readInputState" msgid="8387754901688728043">"앱이 다른 앱과 상호작용할 때에도 사용자가 누르는 키(예: 비밀번호 입력)를 볼 수 있도록 허용합니다. 일반 앱에는 필요하지 않습니다."</string>
<string name="permlab_bindInputMethod" msgid="3360064620230515776">"입력 방법 연결"</string>
<string name="permdesc_bindInputMethod" msgid="3250440322807286331">"권한을 가진 프로그램이 입력 방법에 대한 최상위 인터페이스를 사용하도록 허용합니다. 일반 앱에는 필요하지 않습니다."</string>
+ <string name="permlab_bindAccessibilityService" msgid="5357733942556031593">"접근성 서비스와 연결"</string>
+ <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"권한을 가진 프로그램이 접근성 서비스에 대한 최상위 인터페이스를 사용하도록 허용합니다. 일반 앱에는 필요하지 않습니다."</string>
<string name="permlab_bindTextService" msgid="7358378401915287938">"텍스트 서비스 연결"</string>
<string name="permdesc_bindTextService" msgid="8151968910973998670">"권한을 가진 프로그램이 텍스트 서비스(예: SpellCheckerService)에 대한 최상위 인터페이스를 사용하도록 허용합니다. 일반 앱에는 필요하지 않습니다."</string>
<string name="permlab_bindVpnService" msgid="4708596021161473255">"VPN 서비스와 연결"</string>
@@ -853,6 +855,9 @@
<string name="searchview_description_clear" msgid="1330281990951833033">"검색어 삭제"</string>
<string name="searchview_description_submit" msgid="2688450133297983542">"검색어 보내기"</string>
<string name="searchview_description_voice" msgid="2453203695674994440">"음성 검색"</string>
+ <string name="enable_explore_by_touch_warning_title" msgid="7460694070309730149">"\'터치하여 탐색\'을 사용하시겠습니까?"</string>
+ <string name="enable_explore_by_touch_warning_message" product="tablet" msgid="8655887539089910577">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g>을(를) 사용하려면 \'터치하여 탐색\' 기능을 사용하도록 설정해야 합니다. \'터치하여 탐색\'을 사용하도록 설정하면, 화면을 터치하여 손가락 아래에 표시된 항목에 대한 설명을 듣고 보거나 태블릿으로 상호작용하기 위한 동작을 수행할 수 있습니다."</string>
+ <string name="enable_explore_by_touch_warning_message" product="default" msgid="2708199672852373195">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g>을(를) 사용하려면 \'터치하여 탐색\' 기능을 사용하도록 설정해야 합니다. \'터치하여 탐색\'을 사용하도록 설정하면, 화면을 터치하여 손가락 아래에 표시된 항목에 대한 설명을 듣고 보거나 휴대전화로 상호작용하기 위한 동작을 수행할 수 있습니다."</string>
<string name="oneMonthDurationPast" msgid="7396384508953779925">"한 달 전"</string>
<string name="beforeOneMonthDurationPast" msgid="909134546836499826">"한 달 전"</string>
<plurals name="num_seconds_ago">
@@ -1119,6 +1124,8 @@
<string name="configure_input_methods" msgid="9091652157722495116">"입력 방법 설정"</string>
<string name="use_physical_keyboard" msgid="6203112478095117625">"물리적 키보드"</string>
<string name="hardware" msgid="7517821086888990278">"하드웨어"</string>
+ <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"키보드 레이아웃 선택"</string>
+ <string name="select_keyboard_layout_notification_message" msgid="4465907700449257063">"터치하여 키보드 레이아웃을 선택합니다."</string>
<string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="candidates_style" msgid="4333913089637062257"><u>"가능한 원인"</u></string>
@@ -1312,5 +1319,5 @@
<string name="launchBrowserDefault" msgid="2057951947297614725">"브라우저를 실행하시겠습니까?"</string>
<string name="SetupCallDefault" msgid="5834948469253758575">"통화를 수락하시겠습니까?"</string>
<string name="activity_resolver_use_always" msgid="8017770747801494933">"항상"</string>
- <string name="activity_resolver_use_once" msgid="405646673463328329">"한 번만"</string>
+ <string name="activity_resolver_use_once" msgid="2404644797149173758">"한 번만"</string>
</resources>
diff --git a/core/res/res/values-large/config.xml b/core/res/res/values-large/config.xml
index 9327200..d1ec4ef 100644
--- a/core/res/res/values-large/config.xml
+++ b/core/res/res/values-large/config.xml
@@ -24,9 +24,6 @@
<dimen name="config_prefDialogWidth">440dp</dimen>
<!-- see comment in values/config.xml -->
- <integer name="config_longPressOnPowerBehavior">2</integer>
-
- <!-- see comment in values/config.xml -->
<integer name="config_longPressOnHomeBehavior">0</integer>
</resources>
diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml
index f5132c1..52b7a4b 100644
--- a/core/res/res/values-lt/strings.xml
+++ b/core/res/res/values-lt/strings.xml
@@ -317,6 +317,8 @@
<string name="permdesc_readInputState" msgid="8387754901688728043">"Leidžiama programai stebėti paspaudžiamus klavišus, net kai sąveikaujama su kita programa (pvz., įvedant slaptažodį). Įprastoms programoms to neturėtų prireikti."</string>
<string name="permlab_bindInputMethod" msgid="3360064620230515776">"susaistyti įvesties būdą"</string>
<string name="permdesc_bindInputMethod" msgid="3250440322807286331">"Leidžiama savininką susaistyti su įvesties metodo aukščiausio lygio sąsaja. Įprastoms programoms to neturėtų prireikti."</string>
+ <string name="permlab_bindAccessibilityService" msgid="5357733942556031593">"susisaistyti su pasiekiamumo paslauga"</string>
+ <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Savininkui leidžiama susisaistyti su aukščiausio lygio pasiekiamumo paslaugos sąsaja. Įprastoms programoms to neturėtų prireikti."</string>
<string name="permlab_bindTextService" msgid="7358378401915287938">"priskirti teksto paslaugą"</string>
<string name="permdesc_bindTextService" msgid="8151968910973998670">"Leidžiama savininkui priskirti aukščiausio lygio teksto paslaugos (pvz., „SpellCheckerService“) sąsają. Įprastoms programoms to neturėtų prireikti."</string>
<string name="permlab_bindVpnService" msgid="4708596021161473255">"susaistyti su VPN paslauga"</string>
@@ -853,6 +855,9 @@
<string name="searchview_description_clear" msgid="1330281990951833033">"Išvalyti užklausą"</string>
<string name="searchview_description_submit" msgid="2688450133297983542">"Patvirtinti užklausą"</string>
<string name="searchview_description_voice" msgid="2453203695674994440">"Paieška balsu"</string>
+ <string name="enable_explore_by_touch_warning_title" msgid="7460694070309730149">"Įgalinti naršymą liečiant?"</string>
+ <string name="enable_explore_by_touch_warning_message" product="tablet" msgid="8655887539089910577">"„<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g>“ nori įgalinti naršymą liečiant. Kai naršymas liečiant bus įjungtas, galėsite išgirsti ar peržiūrėti pirštu liečiamų elementų aprašus arba atlikdami gestus naudoti planšetinį kompiuterį."</string>
+ <string name="enable_explore_by_touch_warning_message" product="default" msgid="2708199672852373195">"„<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g>“ nori įgalinti naršymą liečiant. Kai naršymas liečiant bus įjungtas, galėsite išgirsti ar peržiūrėti pirštu liečiamų elementų aprašus arba atlikdami gestus naudoti telefoną."</string>
<string name="oneMonthDurationPast" msgid="7396384508953779925">"Prieš 1 mėn."</string>
<string name="beforeOneMonthDurationPast" msgid="909134546836499826">"Prieš maždaug 1 mėnesį"</string>
<plurals name="num_seconds_ago">
@@ -1119,6 +1124,8 @@
<string name="configure_input_methods" msgid="9091652157722495116">"Nustatyti įvesties metodus"</string>
<string name="use_physical_keyboard" msgid="6203112478095117625">"Fizinė klaviatūra"</string>
<string name="hardware" msgid="7517821086888990278">"Apar. įr."</string>
+ <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"Pasirinkite klaviatūros išdėstymą"</string>
+ <string name="select_keyboard_layout_notification_message" msgid="4465907700449257063">"Palieskite, kad pasirinktumėte klaviatūros išdėstymą."</string>
<string name="fast_scroll_alphabet" msgid="5433275485499039199">" AĄBCČDEĘĖFGHIĮYJKLMNOPRSŠTUŲŪVZŽ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789AĄBCČDEĘĖFGHIĮYJKLMNOPRSŠTUŲŪVZŽ"</string>
<string name="candidates_style" msgid="4333913089637062257"><u>"kandidatai"</u></string>
@@ -1312,5 +1319,5 @@
<string name="launchBrowserDefault" msgid="2057951947297614725">"Paleisti naršyklę?"</string>
<string name="SetupCallDefault" msgid="5834948469253758575">"Priimti skambutį?"</string>
<string name="activity_resolver_use_always" msgid="8017770747801494933">"Visada"</string>
- <string name="activity_resolver_use_once" msgid="405646673463328329">"Tik kartą"</string>
+ <string name="activity_resolver_use_once" msgid="2404644797149173758">"Tik kartą"</string>
</resources>
diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml
index e6c8d99..1fb76f6 100644
--- a/core/res/res/values-lv/strings.xml
+++ b/core/res/res/values-lv/strings.xml
@@ -317,6 +317,8 @@
<string name="permdesc_readInputState" msgid="8387754901688728043">"Ļauj lietotnei skatīt taustiņus, ko nospiežat, pat ja darbojaties citā lietotnē (piemēram, ievadot paroli). Parastajām lietotnēm tas nekad nav nepieciešams."</string>
<string name="permlab_bindInputMethod" msgid="3360064620230515776">"saistīt ar ievades metodi"</string>
<string name="permdesc_bindInputMethod" msgid="3250440322807286331">"Ļauj īpašniekam izveidot saiti ar ievades metodes augstākā līmeņa saskarni. Parastajām lietotnēm tas nekad nav nepieciešams."</string>
+ <string name="permlab_bindAccessibilityService" msgid="5357733942556031593">"saistīt ar pieejamības pakalpojumu"</string>
+ <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Ļauj īpašniekam izveidot saiti ar pieejamības pakalpojuma augšējā līmeņa saskarni. Parastajām lietotnēm šī atļauja nav nepieciešama."</string>
<string name="permlab_bindTextService" msgid="7358378401915287938">"saistīt ar īsziņu pakalpojumu"</string>
<string name="permdesc_bindTextService" msgid="8151968910973998670">"Ļauj īpašniekam veikt saistīšanu ar īsziņu pakalpojuma augstākā līmeņa saskarni (piem., SpellCheckerService). Parastajām lietotnēm tas nekad nav nepieciešams."</string>
<string name="permlab_bindVpnService" msgid="4708596021161473255">"saistīt ar VPN pakalpojumu"</string>
@@ -853,6 +855,9 @@
<string name="searchview_description_clear" msgid="1330281990951833033">"Notīrīt vaicājumu"</string>
<string name="searchview_description_submit" msgid="2688450133297983542">"Iesniedziet vaicājumu."</string>
<string name="searchview_description_voice" msgid="2453203695674994440">"Meklēšana ar balsi"</string>
+ <string name="enable_explore_by_touch_warning_title" msgid="7460694070309730149">"Vai iesp. “Pārlūkot pieskaroties”?"</string>
+ <string name="enable_explore_by_touch_warning_message" product="tablet" msgid="8655887539089910577">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> vēlas iespējot funkciju “Atklāt pieskaroties”. Kad ir ieslēgta funkcija “Atklāt pieskaroties”, var dzirdēt vai redzēt tā vienuma aprakstu, virs kura atrodas pirksts, vai veikt žestus, lai mijiedarbotos ar planšetdatoru."</string>
+ <string name="enable_explore_by_touch_warning_message" product="default" msgid="2708199672852373195">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> vēlas iespējot funkciju “Atklāt pieskaroties”. Kad ir ieslēgta funkcija “Atklāt pieskaroties”, var dzirdēt vai redzēt tā vienuma aprakstu, virs kura atrodas pirksts, vai veikt žestus, lai mijiedarbotos ar tālruni."</string>
<string name="oneMonthDurationPast" msgid="7396384508953779925">"Pirms 1 mēneša"</string>
<string name="beforeOneMonthDurationPast" msgid="909134546836499826">"Vairāk nekā pirms 1 mēneša"</string>
<plurals name="num_seconds_ago">
@@ -1119,6 +1124,8 @@
<string name="configure_input_methods" msgid="9091652157722495116">"Iestatīt ievades metodes"</string>
<string name="use_physical_keyboard" msgid="6203112478095117625">"Fiziskā tastatūra"</string>
<string name="hardware" msgid="7517821086888990278">"Aparatūra"</string>
+ <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"Atlasiet tastatūras izkārtojumu"</string>
+ <string name="select_keyboard_layout_notification_message" msgid="4465907700449257063">"Pieskarieties, lai atlasītu tastatūras izkārtojumu."</string>
<string name="fast_scroll_alphabet" msgid="5433275485499039199">" AĀBCČDEĒFGĢHIĪJKĶLĻMNŅOPRSŠTUŪVZŽ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789AĀBCČDEĒFGĢHIĪJKĶLĻMNŅOPRSŠTUŪVZŽ"</string>
<string name="candidates_style" msgid="4333913089637062257"><u>"kandidāti"</u></string>
@@ -1312,5 +1319,5 @@
<string name="launchBrowserDefault" msgid="2057951947297614725">"Vai palaist pārlūkprogrammu?"</string>
<string name="SetupCallDefault" msgid="5834948469253758575">"Vai atbildēt uz zvanu?"</string>
<string name="activity_resolver_use_always" msgid="8017770747801494933">"Vienmēr"</string>
- <string name="activity_resolver_use_once" msgid="405646673463328329">"Tikai vienreiz"</string>
+ <string name="activity_resolver_use_once" msgid="2404644797149173758">"Tikai vienreiz"</string>
</resources>
diff --git a/core/res/res/values-ms/strings.xml b/core/res/res/values-ms/strings.xml
index 1ab7002..2168b9a 100644
--- a/core/res/res/values-ms/strings.xml
+++ b/core/res/res/values-ms/strings.xml
@@ -317,6 +317,8 @@
<string name="permdesc_readInputState" msgid="8387754901688728043">"Membenarkan apl untuk melihat kekunci yang anda tekan walaupun semasa berinteraksi dengan apl lain (seperti menaip kata laluan). Tidak sekali-kali diperlukan untuk apl biasa."</string>
<string name="permlab_bindInputMethod" msgid="3360064620230515776">"terikat kepada kaedah input"</string>
<string name="permdesc_bindInputMethod" msgid="3250440322807286331">"Membenarkan pemegang terikat dengan antara muka peringkat tertinggi bagi kaedah input itu. Tidak sekali-kali diperlukan untuk apl biasa."</string>
+ <string name="permlab_bindAccessibilityService" msgid="5357733942556031593">"terikat kepada perkhidmatan yang boleh diakses"</string>
+ <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Membenarkan pemegang terikat dengan antara muka peringkat tertinggi bagi perkhidmatan yang boleh diakses. Tidak sekali-kali diperlukan untuk apl biasa."</string>
<string name="permlab_bindTextService" msgid="7358378401915287938">"terikat kepada perkhidmatan teks"</string>
<string name="permdesc_bindTextService" msgid="8151968910973998670">"Membenarkan pemegang mengikat kepada antara muka peringkat atasan perkhidmatan teks(mis. PerkhidmatanPenyemakEjaan). Tidak seharusnya diperlukan untuk apl biasa."</string>
<string name="permlab_bindVpnService" msgid="4708596021161473255">"terikat kepada perkhidmatan VPN"</string>
@@ -853,6 +855,9 @@
<string name="searchview_description_clear" msgid="1330281990951833033">"Pertanyaan jelas"</string>
<string name="searchview_description_submit" msgid="2688450133297983542">"Serah pertanyaan"</string>
<string name="searchview_description_voice" msgid="2453203695674994440">"Carian suara"</string>
+ <string name="enable_explore_by_touch_warning_title" msgid="7460694070309730149">"Dayakan Jelajah melalui Sentuhan?"</string>
+ <string name="enable_explore_by_touch_warning_message" product="tablet" msgid="8655887539089910577">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> ingin mendayakan Jelajah melalui Sentuhan. Apabila Jelajah melalui Sentuhan didayakan, anda boleh mendengar atau melihat penerangan tentang apa di bawah jari anda atau melakukan gerak isyarat untuk berinteraksi dengan tablet."</string>
+ <string name="enable_explore_by_touch_warning_message" product="default" msgid="2708199672852373195">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> ingin mendayakan Jelajah melalui Sentuhan. Apabila Jelajah melalui Sentuhan didayakan, anda boleh mendengar atau melihat penerangan tentang apa di bawah jari anda atau melakukan gerak isyarat untuk berinteraksi dengan telefon."</string>
<string name="oneMonthDurationPast" msgid="7396384508953779925">"1 bulan yang lalu"</string>
<string name="beforeOneMonthDurationPast" msgid="909134546836499826">"Sebelum 1 bulan yang lalu"</string>
<plurals name="num_seconds_ago">
@@ -1119,6 +1124,8 @@
<string name="configure_input_methods" msgid="9091652157722495116">"Sediakan kaedah input"</string>
<string name="use_physical_keyboard" msgid="6203112478095117625">"Papan kekunci fizikal"</string>
<string name="hardware" msgid="7517821086888990278">"Perkakasan"</string>
+ <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"Pilih susun atur papan kekunci"</string>
+ <string name="select_keyboard_layout_notification_message" msgid="4465907700449257063">"Sentuh untuk memilih susun atur papan kekunci."</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>"calon"</u></string>
@@ -1312,5 +1319,5 @@
<string name="launchBrowserDefault" msgid="2057951947297614725">"Lancarkan Penyemak Imbas?"</string>
<string name="SetupCallDefault" msgid="5834948469253758575">"Terima panggilan?"</string>
<string name="activity_resolver_use_always" msgid="8017770747801494933">"Sentiasa"</string>
- <string name="activity_resolver_use_once" msgid="405646673463328329">"Hanya Sekali"</string>
+ <string name="activity_resolver_use_once" msgid="2404644797149173758">"Hanya sekali"</string>
</resources>
diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml
index a0e00eb..47935fd 100644
--- a/core/res/res/values-nb/strings.xml
+++ b/core/res/res/values-nb/strings.xml
@@ -317,6 +317,8 @@
<string name="permdesc_readInputState" msgid="8387754901688728043">"Lar appen se hvilke taster du trykker på, selv når du samhandler med en annen app (f.eks. skriver inn et passord). Skal aldri være nødvendig for vanlige apper."</string>
<string name="permlab_bindInputMethod" msgid="3360064620230515776">"binde til en inndatametode"</string>
<string name="permdesc_bindInputMethod" msgid="3250440322807286331">"Lar innehaveren binde det øverste nivået av grensesnittet til en inndatametode. Skal aldri være nødvendig for normale apper."</string>
+ <string name="permlab_bindAccessibilityService" msgid="5357733942556031593">"binde seg til en tilgjengelighetstjeneste"</string>
+ <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Gir innehaveren tillatelse til å bindes til det øverste nivået av grensesnittet for en tilgjengelighetstjeneste. Skal aldri være nødvendig for vanlige apper."</string>
<string name="permlab_bindTextService" msgid="7358378401915287938">"binde til en teksttjeneste"</string>
<string name="permdesc_bindTextService" msgid="8151968910973998670">"Lar innehaveren binde seg til øverste grensesnittnivå for en teksttjeneste (f.eks. SpellCheckerService). Skal aldri være nødvendig for vanlige apper."</string>
<string name="permlab_bindVpnService" msgid="4708596021161473255">"binde deg til en VPN-tjeneste"</string>
@@ -853,6 +855,12 @@
<string name="searchview_description_clear" msgid="1330281990951833033">"Slett søket"</string>
<string name="searchview_description_submit" msgid="2688450133297983542">"Send inn spørsmål"</string>
<string name="searchview_description_voice" msgid="2453203695674994440">"Talesøk"</string>
+ <!-- no translation found for enable_explore_by_touch_warning_title (7460694070309730149) -->
+ <skip />
+ <!-- no translation found for enable_explore_by_touch_warning_message (8655887539089910577) -->
+ <skip />
+ <!-- no translation found for enable_explore_by_touch_warning_message (2708199672852373195) -->
+ <skip />
<string name="oneMonthDurationPast" msgid="7396384508953779925">"For én måned siden"</string>
<string name="beforeOneMonthDurationPast" msgid="909134546836499826">"For over en måned siden"</string>
<plurals name="num_seconds_ago">
@@ -1119,6 +1127,10 @@
<string name="configure_input_methods" msgid="9091652157722495116">"Konfigurer inndatametoder"</string>
<string name="use_physical_keyboard" msgid="6203112478095117625">"Fysisk tastatur"</string>
<string name="hardware" msgid="7517821086888990278">"Maskinvare"</string>
+ <!-- no translation found for select_keyboard_layout_notification_title (1407367017263030773) -->
+ <skip />
+ <!-- no translation found for select_keyboard_layout_notification_message (4465907700449257063) -->
+ <skip />
<string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZÆØÅ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZÆØÅ"</string>
<string name="candidates_style" msgid="4333913089637062257">"TAG_FONT"<u>"kandidater"</u>"CLOSE_FONT"</string>
@@ -1312,5 +1324,6 @@
<string name="launchBrowserDefault" msgid="2057951947297614725">"Vil du starte nettleseren?"</string>
<string name="SetupCallDefault" msgid="5834948469253758575">"Vil du besvare anropet?"</string>
<string name="activity_resolver_use_always" msgid="8017770747801494933">"Alltid"</string>
- <string name="activity_resolver_use_once" msgid="405646673463328329">"Bare én gang"</string>
+ <!-- no translation found for activity_resolver_use_once (2404644797149173758) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml
index dfd67ff..4ad7180 100644
--- a/core/res/res/values-nl/strings.xml
+++ b/core/res/res/values-nl/strings.xml
@@ -317,6 +317,8 @@
<string name="permdesc_readInputState" msgid="8387754901688728043">"Hiermee kan de app bijhouden op welke toetsen u drukt, zelfs wanneer u een andere app gebruikt (bijvoorbeeld wanneer u een wachtwoord typt). Dit is niet nodig voor normale apps."</string>
<string name="permlab_bindInputMethod" msgid="3360064620230515776">"verbinden aan een invoermethode"</string>
<string name="permdesc_bindInputMethod" msgid="3250440322807286331">"Hiermee kan de houder zich verbinden met de hoofdinterface van een invoermethode. Nooit vereist voor normale apps."</string>
+ <string name="permlab_bindAccessibilityService" msgid="5357733942556031593">"koppelen aan een toegankelijkheidsservice"</string>
+ <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Hiermee wordt de houder toegestaan verbinding te maken met de hoofdinterface van een toegankelijkheidsservice. Nooit vereist voor normale apps."</string>
<string name="permlab_bindTextService" msgid="7358378401915287938">"koppelen aan een sms-service"</string>
<string name="permdesc_bindTextService" msgid="8151968910973998670">"Hiermee kan de gebruiker koppelen met de hoofdinterface van een tekstservice (zoals SpellCheckerService). Dit is niet nodig voor normale apps."</string>
<string name="permlab_bindVpnService" msgid="4708596021161473255">"koppelen aan een VPN-service"</string>
@@ -853,6 +855,12 @@
<string name="searchview_description_clear" msgid="1330281990951833033">"Zoekopdracht wissen"</string>
<string name="searchview_description_submit" msgid="2688450133297983542">"Zoekopdracht verzenden"</string>
<string name="searchview_description_voice" msgid="2453203695674994440">"Spraakgestuurd zoeken"</string>
+ <!-- no translation found for enable_explore_by_touch_warning_title (7460694070309730149) -->
+ <skip />
+ <!-- no translation found for enable_explore_by_touch_warning_message (8655887539089910577) -->
+ <skip />
+ <!-- no translation found for enable_explore_by_touch_warning_message (2708199672852373195) -->
+ <skip />
<string name="oneMonthDurationPast" msgid="7396384508953779925">"1 maand geleden"</string>
<string name="beforeOneMonthDurationPast" msgid="909134546836499826">"Meer dan 1 maand geleden"</string>
<plurals name="num_seconds_ago">
@@ -1119,6 +1127,10 @@
<string name="configure_input_methods" msgid="9091652157722495116">"Invoermethoden instellen"</string>
<string name="use_physical_keyboard" msgid="6203112478095117625">"Fysiek toetsenbord"</string>
<string name="hardware" msgid="7517821086888990278">"Hardware"</string>
+ <!-- no translation found for select_keyboard_layout_notification_title (1407367017263030773) -->
+ <skip />
+ <!-- no translation found for select_keyboard_layout_notification_message (4465907700449257063) -->
+ <skip />
<string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="candidates_style" msgid="4333913089637062257"><u>"kandidaten"</u></string>
@@ -1312,5 +1324,6 @@
<string name="launchBrowserDefault" msgid="2057951947297614725">"Browser starten?"</string>
<string name="SetupCallDefault" msgid="5834948469253758575">"Oproep accepteren?"</string>
<string name="activity_resolver_use_always" msgid="8017770747801494933">"Altijd"</string>
- <string name="activity_resolver_use_once" msgid="405646673463328329">"Alleen nu gebruiken"</string>
+ <!-- no translation found for activity_resolver_use_once (2404644797149173758) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml
index 10effa3..a1cbe5a 100644
--- a/core/res/res/values-pl/strings.xml
+++ b/core/res/res/values-pl/strings.xml
@@ -317,6 +317,8 @@
<string name="permdesc_readInputState" msgid="8387754901688728043">"Pozwala aplikacji na śledzenie naciskanych klawiszy, nawet podczas pracy z innym programem (na przykład podczas wpisywania hasła). Nigdy nie powinno być potrzebne normalnym aplikacjom."</string>
<string name="permlab_bindInputMethod" msgid="3360064620230515776">"powiązanie ze sposobem wprowadzania tekstu"</string>
<string name="permdesc_bindInputMethod" msgid="3250440322807286331">"Pozwala na powiązanie wybranego sposobu wprowadzania tekstu z interfejsem najwyższego poziomu. To uprawnienie nie powinno być nigdy wymagane przez zwykłe aplikacje."</string>
+ <string name="permlab_bindAccessibilityService" msgid="5357733942556031593">"tworzenie powiązania z usługą ułatwień dostępu"</string>
+ <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Zezwala na tworzenie powiązania z interfejsem najwyższego poziomu usługi ułatwień dostępu. Nieprzeznaczone dla zwykłych aplikacji."</string>
<string name="permlab_bindTextService" msgid="7358378401915287938">"tworzenie powiązania z usługą tekstową"</string>
<string name="permdesc_bindTextService" msgid="8151968910973998670">"Pozwala na tworzenie powiązania z interfejsem najwyższego poziomu usługi tekstowej (np. SpellCheckerService). Nie powinno być nigdy potrzebne w przypadku zwykłych aplikacji."</string>
<string name="permlab_bindVpnService" msgid="4708596021161473255">"tworzenie powiązania z usługą VPN"</string>
@@ -853,6 +855,9 @@
<string name="searchview_description_clear" msgid="1330281990951833033">"Wyczyść zapytanie"</string>
<string name="searchview_description_submit" msgid="2688450133297983542">"Wyślij zapytanie"</string>
<string name="searchview_description_voice" msgid="2453203695674994440">"Wyszukiwanie głosowe"</string>
+ <string name="enable_explore_by_touch_warning_title" msgid="7460694070309730149">"Włączyć Czytanie dotykiem?"</string>
+ <string name="enable_explore_by_touch_warning_message" product="tablet" msgid="8655887539089910577">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> chce włączyć Czytanie dotykiem. Gdy ta funkcja jest włączona, słyszysz i widzisz opisy elementów, które są pod Twoim palcem, oraz możesz obsługiwać tablet gestami."</string>
+ <string name="enable_explore_by_touch_warning_message" product="default" msgid="2708199672852373195">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> chce włączyć Czytanie dotykiem. Gdy ta funkcja jest włączona, słyszysz i widzisz opisy elementów, które są pod Twoim palcem, oraz możesz obsługiwać telefon gestami."</string>
<string name="oneMonthDurationPast" msgid="7396384508953779925">"1 miesiąc temu"</string>
<string name="beforeOneMonthDurationPast" msgid="909134546836499826">"Ponad 1 miesiąc temu"</string>
<plurals name="num_seconds_ago">
@@ -974,8 +979,8 @@
<string name="loading" msgid="7933681260296021180">"Wczytywanie…"</string>
<string name="capital_on" msgid="1544682755514494298">"Wł."</string>
<string name="capital_off" msgid="6815870386972805832">"Wył."</string>
- <string name="whichApplication" msgid="4533185947064773386">"Zakończ czynność korzystając z"</string>
- <string name="alwaysUse" msgid="4583018368000610438">"Używaj domyślnie dla tej czynności."</string>
+ <string name="whichApplication" msgid="4533185947064773386">"Zakończ czynność przez..."</string>
+ <string name="alwaysUse" msgid="4583018368000610438">"Domyślne dla tej czynności"</string>
<string name="clearDefaultHintMsg" msgid="3252584689512077257">"Wyczyść wartości domyślne w: Ustawienia systemu &gt; Aplikacje &gt; Pobrane."</string>
<string name="chooseActivity" msgid="7486876147751803333">"Wybierz czynność"</string>
<string name="chooseUsbActivity" msgid="6894748416073583509">"Wybierz aplikację dla urządzenia USB"</string>
@@ -1119,6 +1124,8 @@
<string name="configure_input_methods" msgid="9091652157722495116">"Konfiguruj metody wprowadzania"</string>
<string name="use_physical_keyboard" msgid="6203112478095117625">"Klawiatura fizyczna"</string>
<string name="hardware" msgid="7517821086888990278">"Sprzęt"</string>
+ <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"Wybierz układ klawiatury"</string>
+ <string name="select_keyboard_layout_notification_message" msgid="4465907700449257063">"Kliknij, by wybrać układ klawiatury."</string>
<string name="fast_scroll_alphabet" msgid="5433275485499039199">" AĄBCĆDEĘFGHIJKLŁMNŃOÓPQRSŚTUVWXYZŹŻ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="candidates_style" msgid="4333913089637062257"><u>"kandydaci"</u></string>
@@ -1312,5 +1319,5 @@
<string name="launchBrowserDefault" msgid="2057951947297614725">"Uruchomić przeglądarkę?"</string>
<string name="SetupCallDefault" msgid="5834948469253758575">"Odebrać połączenie?"</string>
<string name="activity_resolver_use_always" msgid="8017770747801494933">"Zawsze"</string>
- <string name="activity_resolver_use_once" msgid="405646673463328329">"Tylko raz"</string>
+ <string name="activity_resolver_use_once" msgid="2404644797149173758">"Tylko raz"</string>
</resources>
diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml
index e7a809c..38ce3ac 100644
--- a/core/res/res/values-pt-rPT/strings.xml
+++ b/core/res/res/values-pt-rPT/strings.xml
@@ -317,6 +317,8 @@
<string name="permdesc_readInputState" msgid="8387754901688728043">"Permite que a aplicação veja as teclas que o utilizador prime, mesmo ao interagir com outra aplicação (como, por exemplo, ao introduzir uma palavra-passe). Nunca deve ser necessário para aplicações normais."</string>
<string name="permlab_bindInputMethod" msgid="3360064620230515776">"vincular a um método de entrada"</string>
<string name="permdesc_bindInputMethod" msgid="3250440322807286331">"Permite ao titular vincular-se à interface de nível superior de um método de entrada. Nunca deve ser necessário para aplicações normais."</string>
+ <string name="permlab_bindAccessibilityService" msgid="5357733942556031593">"vincular a um serviço de acessibilidade"</string>
+ <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Permite que o titular vincule a interface de nível superior de um serviço de acessibilidade. Nunca deverá ser necessário para aplicações normais."</string>
<string name="permlab_bindTextService" msgid="7358378401915287938">"vincular a um serviço de texto"</string>
<string name="permdesc_bindTextService" msgid="8151968910973998670">"Permite ao titular ligar-se à interface de nível superior de um serviço de texto (por exemplo SpellCheckerService). Nunca deverá ser necessário para aplicações normais."</string>
<string name="permlab_bindVpnService" msgid="4708596021161473255">"vincular a um serviço VPN"</string>
@@ -853,6 +855,12 @@
<string name="searchview_description_clear" msgid="1330281990951833033">"Limpar consulta"</string>
<string name="searchview_description_submit" msgid="2688450133297983542">"Enviar consulta"</string>
<string name="searchview_description_voice" msgid="2453203695674994440">"Pesquisa por voz"</string>
+ <!-- no translation found for enable_explore_by_touch_warning_title (7460694070309730149) -->
+ <skip />
+ <!-- no translation found for enable_explore_by_touch_warning_message (8655887539089910577) -->
+ <skip />
+ <!-- no translation found for enable_explore_by_touch_warning_message (2708199672852373195) -->
+ <skip />
<string name="oneMonthDurationPast" msgid="7396384508953779925">"Há 1 mês"</string>
<string name="beforeOneMonthDurationPast" msgid="909134546836499826">"Há mais de 1 mês"</string>
<plurals name="num_seconds_ago">
@@ -1119,6 +1127,10 @@
<string name="configure_input_methods" msgid="9091652157722495116">"Configurar métodos de introdução"</string>
<string name="use_physical_keyboard" msgid="6203112478095117625">"Teclado físico"</string>
<string name="hardware" msgid="7517821086888990278">"Hardware"</string>
+ <!-- no translation found for select_keyboard_layout_notification_title (1407367017263030773) -->
+ <skip />
+ <!-- no translation found for select_keyboard_layout_notification_message (4465907700449257063) -->
+ <skip />
<string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="candidates_style" msgid="4333913089637062257"><u>"candidatos"</u></string>
@@ -1312,5 +1324,6 @@
<string name="launchBrowserDefault" msgid="2057951947297614725">"Iniciar Navegador?"</string>
<string name="SetupCallDefault" msgid="5834948469253758575">"Aceitar chamada?"</string>
<string name="activity_resolver_use_always" msgid="8017770747801494933">"Sempre"</string>
- <string name="activity_resolver_use_once" msgid="405646673463328329">"Só Uma Vez"</string>
+ <!-- no translation found for activity_resolver_use_once (2404644797149173758) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml
index 84ce4bb..3acafb1 100644
--- a/core/res/res/values-pt/strings.xml
+++ b/core/res/res/values-pt/strings.xml
@@ -317,6 +317,8 @@
<string name="permdesc_readInputState" msgid="8387754901688728043">"Permite que o aplicativo veja as teclas pressionadas mesmo quando você estiver interagindo com outro aplicativo, como ao digitar uma senha. Nunca deve ser necessário para aplicativos normais."</string>
<string name="permlab_bindInputMethod" msgid="3360064620230515776">"vincular a um método de entrada"</string>
<string name="permdesc_bindInputMethod" msgid="3250440322807286331">"Permite que o proprietário utilize a interface de nível superior de um método de entrada. Nunca deve ser necessário para aplicativos normais."</string>
+ <string name="permlab_bindAccessibilityService" msgid="5357733942556031593">"usar um serviço de acessibilidade"</string>
+ <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Permite que o proprietário use a interface de nível superior de um serviço de acessibilidade. Nunca deve ser necessário para aplicativos comuns."</string>
<string name="permlab_bindTextService" msgid="7358378401915287938">"sujeitar-se a um serviço de texto"</string>
<string name="permdesc_bindTextService" msgid="8151968910973998670">"Permite que o proprietário utilize interface de nível superior de um serviço de texto (por exemplo, SpellCheckerService). Nunca deve ser necessário para aplicativos normais."</string>
<string name="permlab_bindVpnService" msgid="4708596021161473255">"se ligam a um serviço de VPN"</string>
@@ -853,6 +855,9 @@
<string name="searchview_description_clear" msgid="1330281990951833033">"Limpar consulta"</string>
<string name="searchview_description_submit" msgid="2688450133297983542">"Enviar consulta"</string>
<string name="searchview_description_voice" msgid="2453203695674994440">"Pesquisa por voz"</string>
+ <string name="enable_explore_by_touch_warning_title" msgid="7460694070309730149">"Ativar exploração pelo toque?"</string>
+ <string name="enable_explore_by_touch_warning_message" product="tablet" msgid="8655887539089910577">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> quer ativar a exploração pelo toque. Com ela, você pode ouvir ou ver descrições do que está sob seu dedo e interagir com o tablet através de gestos."</string>
+ <string name="enable_explore_by_touch_warning_message" product="default" msgid="2708199672852373195">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> quer ativar a exploração pelo toque. Com ela, você pode ouvir ou ver descrições do que está sob seu dedo e interagir com o telefone através de gestos."</string>
<string name="oneMonthDurationPast" msgid="7396384508953779925">"1 mês atrás"</string>
<string name="beforeOneMonthDurationPast" msgid="909134546836499826">"Antes de 1 mês atrás"</string>
<plurals name="num_seconds_ago">
@@ -1119,6 +1124,8 @@
<string name="configure_input_methods" msgid="9091652157722495116">"Configurar métodos de entrada"</string>
<string name="use_physical_keyboard" msgid="6203112478095117625">"Teclado físico"</string>
<string name="hardware" msgid="7517821086888990278">"Hardware"</string>
+ <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"Selecione o layout de teclado"</string>
+ <string name="select_keyboard_layout_notification_message" msgid="4465907700449257063">"Toque para selecionar um layout de teclado."</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>"candidatos"</u></string>
@@ -1312,5 +1319,5 @@
<string name="launchBrowserDefault" msgid="2057951947297614725">"Abrir Navegador?"</string>
<string name="SetupCallDefault" msgid="5834948469253758575">"Aceitar chamada?"</string>
<string name="activity_resolver_use_always" msgid="8017770747801494933">"Sempre"</string>
- <string name="activity_resolver_use_once" msgid="405646673463328329">"Só uma vez"</string>
+ <string name="activity_resolver_use_once" msgid="2404644797149173758">"Só uma vez"</string>
</resources>
diff --git a/core/res/res/values-rm/strings.xml b/core/res/res/values-rm/strings.xml
index e22bb14..397b095 100644
--- a/core/res/res/values-rm/strings.xml
+++ b/core/res/res/values-rm/strings.xml
@@ -474,6 +474,10 @@
<string name="permlab_bindInputMethod" msgid="3360064620230515776">"associar cun ina metoda d\'endataziun"</string>
<!-- no translation found for permdesc_bindInputMethod (3250440322807286331) -->
<skip />
+ <!-- no translation found for permlab_bindAccessibilityService (5357733942556031593) -->
+ <skip />
+ <!-- no translation found for permdesc_bindAccessibilityService (7034615928609331368) -->
+ <skip />
<!-- no translation found for permlab_bindTextService (7358378401915287938) -->
<skip />
<!-- no translation found for permdesc_bindTextService (8151968910973998670) -->
@@ -1358,6 +1362,12 @@
<skip />
<!-- no translation found for searchview_description_voice (2453203695674994440) -->
<skip />
+ <!-- no translation found for enable_explore_by_touch_warning_title (7460694070309730149) -->
+ <skip />
+ <!-- no translation found for enable_explore_by_touch_warning_message (8655887539089910577) -->
+ <skip />
+ <!-- no translation found for enable_explore_by_touch_warning_message (2708199672852373195) -->
+ <skip />
<string name="oneMonthDurationPast" msgid="7396384508953779925">"Avant 1 mais"</string>
<string name="beforeOneMonthDurationPast" msgid="909134546836499826">"Avant dapli ch\'in mais"</string>
<plurals name="num_seconds_ago">
@@ -1732,6 +1742,10 @@
<skip />
<!-- no translation found for hardware (7517821086888990278) -->
<skip />
+ <!-- no translation found for select_keyboard_layout_notification_title (1407367017263030773) -->
+ <skip />
+ <!-- no translation found for select_keyboard_layout_notification_message (4465907700449257063) -->
+ <skip />
<string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="candidates_style" msgid="4333913089637062257"><u>"candidats"</u></string>
@@ -2071,6 +2085,6 @@
<skip />
<!-- no translation found for activity_resolver_use_always (8017770747801494933) -->
<skip />
- <!-- no translation found for activity_resolver_use_once (405646673463328329) -->
+ <!-- no translation found for activity_resolver_use_once (2404644797149173758) -->
<skip />
</resources>
diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml
index dd639858..52fd28e 100644
--- a/core/res/res/values-ro/strings.xml
+++ b/core/res/res/values-ro/strings.xml
@@ -317,6 +317,8 @@
<string name="permdesc_readInputState" msgid="8387754901688728043">"Permite aplicaţiei să monitorizeze tastele pe care le apăsaţi când interacţionaţi cu o altă aplicaţie (cum ar fi introducerea unei parole). Nu ar trebui să fie niciodată necesară pentru aplicaţiile obişnuite."</string>
<string name="permlab_bindInputMethod" msgid="3360064620230515776">"conectare la o metodă de intrare"</string>
<string name="permdesc_bindInputMethod" msgid="3250440322807286331">"Permite proprietarului să se conecteze la interfaţa de nivel superior a unei metode de introducere. Nu ar trebui să fie niciodată necesară pentru aplicaţiile obişnuite."</string>
+ <string name="permlab_bindAccessibilityService" msgid="5357733942556031593">"conectare la un serviciu de accesibilitate"</string>
+ <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Permite proprietarului să se conecteze la interfaţa de nivel superior a unui serviciu de accesibilitate. Nu ar trebui să fie niciodată necesară pentru aplicaţiile obişnuite."</string>
<string name="permlab_bindTextService" msgid="7358378401915287938">"conectare la un serviciu text"</string>
<string name="permdesc_bindTextService" msgid="8151968910973998670">"Permite proprietarului să se conecteze la o interfaţă de nivel superior a unui serviciu text (de ex., SpellCheckerService). Nu ar trebui să fie niciodată necesară pentru aplicaţiile obişnuite."</string>
<string name="permlab_bindVpnService" msgid="4708596021161473255">"conectare la un serviciu VPN"</string>
@@ -853,6 +855,12 @@
<string name="searchview_description_clear" msgid="1330281990951833033">"Ştergeţi interogarea"</string>
<string name="searchview_description_submit" msgid="2688450133297983542">"Trimiteţi interogarea"</string>
<string name="searchview_description_voice" msgid="2453203695674994440">"Căutare vocală"</string>
+ <!-- no translation found for enable_explore_by_touch_warning_title (7460694070309730149) -->
+ <skip />
+ <!-- no translation found for enable_explore_by_touch_warning_message (8655887539089910577) -->
+ <skip />
+ <!-- no translation found for enable_explore_by_touch_warning_message (2708199672852373195) -->
+ <skip />
<string name="oneMonthDurationPast" msgid="7396384508953779925">"cu 1 lună în urmă"</string>
<string name="beforeOneMonthDurationPast" msgid="909134546836499826">"Cu mai mult de 1 lună în urmă"</string>
<plurals name="num_seconds_ago">
@@ -1119,6 +1127,10 @@
<string name="configure_input_methods" msgid="9091652157722495116">"Configurare metode introducere"</string>
<string name="use_physical_keyboard" msgid="6203112478095117625">"Tastatură fizică"</string>
<string name="hardware" msgid="7517821086888990278">"Hardware"</string>
+ <!-- no translation found for select_keyboard_layout_notification_title (1407367017263030773) -->
+ <skip />
+ <!-- no translation found for select_keyboard_layout_notification_message (4465907700449257063) -->
+ <skip />
<string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="candidates_style" msgid="4333913089637062257"><u>"candidaţi"</u></string>
@@ -1312,5 +1324,6 @@
<string name="launchBrowserDefault" msgid="2057951947297614725">"Lansaţi browserul?"</string>
<string name="SetupCallDefault" msgid="5834948469253758575">"Acceptaţi apelul?"</string>
<string name="activity_resolver_use_always" msgid="8017770747801494933">"Întotdeauna"</string>
- <string name="activity_resolver_use_once" msgid="405646673463328329">"Doar o singură dată"</string>
+ <!-- no translation found for activity_resolver_use_once (2404644797149173758) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml
index 899f13a..75face4 100644
--- a/core/res/res/values-ru/strings.xml
+++ b/core/res/res/values-ru/strings.xml
@@ -317,6 +317,8 @@
<string name="permdesc_readInputState" msgid="8387754901688728043">"Приложение сможет отслеживать нажатие пользователем клавиш даже при работе с другими программами (например, при вводе пароля). Это разрешение не используется обычными приложениями."</string>
<string name="permlab_bindInputMethod" msgid="3360064620230515776">"связывать с методом ввода"</string>
<string name="permdesc_bindInputMethod" msgid="3250440322807286331">"Приложение сможет подключаться к базовому интерфейсу системы ввода. Это разрешение не используется обычными приложениями."</string>
+ <string name="permlab_bindAccessibilityService" msgid="5357733942556031593">"подключаться к службе спецвозможностей"</string>
+ <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Приложение сможет подключаться к базовому интерфейсу службы специальных возможностей. Это разрешение не используется обычными приложениями."</string>
<string name="permlab_bindTextService" msgid="7358378401915287938">"привязка к службе текстовых сообщений"</string>
<string name="permdesc_bindTextService" msgid="8151968910973998670">"Позволяет подключаться к базовому интерфейсу службы текстовых сообщений (например, SpellCheckerService). Это разрешение не используется обычными приложениями."</string>
<string name="permlab_bindVpnService" msgid="4708596021161473255">"подключаться к VPN-службе"</string>
@@ -853,6 +855,12 @@
<string name="searchview_description_clear" msgid="1330281990951833033">"Удалить запрос"</string>
<string name="searchview_description_submit" msgid="2688450133297983542">"Отправить запрос"</string>
<string name="searchview_description_voice" msgid="2453203695674994440">"Голосовой поиск"</string>
+ <!-- no translation found for enable_explore_by_touch_warning_title (7460694070309730149) -->
+ <skip />
+ <!-- no translation found for enable_explore_by_touch_warning_message (8655887539089910577) -->
+ <skip />
+ <!-- no translation found for enable_explore_by_touch_warning_message (2708199672852373195) -->
+ <skip />
<string name="oneMonthDurationPast" msgid="7396384508953779925">"1 месяц назад"</string>
<string name="beforeOneMonthDurationPast" msgid="909134546836499826">"Более месяца назад"</string>
<plurals name="num_seconds_ago">
@@ -1119,6 +1127,10 @@
<string name="configure_input_methods" msgid="9091652157722495116">"Настройка способов ввода"</string>
<string name="use_physical_keyboard" msgid="6203112478095117625">"Физическая клавиатура"</string>
<string name="hardware" msgid="7517821086888990278">"Аппаратура"</string>
+ <!-- no translation found for select_keyboard_layout_notification_title (1407367017263030773) -->
+ <skip />
+ <!-- no translation found for select_keyboard_layout_notification_message (4465907700449257063) -->
+ <skip />
<string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="candidates_style" msgid="4333913089637062257"><u>"варианты"</u></string>
@@ -1312,5 +1324,6 @@
<string name="launchBrowserDefault" msgid="2057951947297614725">"Запустить браузер?"</string>
<string name="SetupCallDefault" msgid="5834948469253758575">"Ответить?"</string>
<string name="activity_resolver_use_always" msgid="8017770747801494933">"Всегда"</string>
- <string name="activity_resolver_use_once" msgid="405646673463328329">"Только сейчас"</string>
+ <!-- no translation found for activity_resolver_use_once (2404644797149173758) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml
index 79cb76a..6f1c5e7 100644
--- a/core/res/res/values-sk/strings.xml
+++ b/core/res/res/values-sk/strings.xml
@@ -317,6 +317,8 @@
<string name="permdesc_readInputState" msgid="8387754901688728043">"Umožňuje aplikácii sledovať, ktoré klávesy stlačíte, dokonca aj keď pracujete s inou aplikáciou (napr. zadávanie hesla). Bežné aplikácie by toto nastavenie nemali nikdy potrebovať."</string>
<string name="permlab_bindInputMethod" msgid="3360064620230515776">"väzba na metódu vstupu"</string>
<string name="permdesc_bindInputMethod" msgid="3250440322807286331">"Umožňuje držiteľovi viazať sa na najvyššiu úroveň rozhrania metódy vstupu. Bežné aplikácie by toto nastavenie nemali nikdy potrebovať."</string>
+ <string name="permlab_bindAccessibilityService" msgid="5357733942556031593">"viazať na službu zjednodušeného ovládania"</string>
+ <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Umožňuje držiteľovi viazať sa na najvyššiu úroveň rozhrania služby zjednodušeného ovládania. Bežné aplikácie by toto nastavenie nemali nikdy potrebovať."</string>
<string name="permlab_bindTextService" msgid="7358378401915287938">"väzba na textovú službu"</string>
<string name="permdesc_bindTextService" msgid="8151968910973998670">"Umožňuje držiteľovi viazať sa na najvyššiu úroveň rozhrania textovej služby (napr. SpellCheckerService). Bežné aplikácie by toto nastavenie nemali nikdy potrebovať."</string>
<string name="permlab_bindVpnService" msgid="4708596021161473255">"Zaviazať k službe VPN"</string>
@@ -853,6 +855,12 @@
<string name="searchview_description_clear" msgid="1330281990951833033">"Jasný dopyt"</string>
<string name="searchview_description_submit" msgid="2688450133297983542">"Odoslať dopyt"</string>
<string name="searchview_description_voice" msgid="2453203695674994440">"Hlasové vyhľadávanie"</string>
+ <!-- no translation found for enable_explore_by_touch_warning_title (7460694070309730149) -->
+ <skip />
+ <!-- no translation found for enable_explore_by_touch_warning_message (8655887539089910577) -->
+ <skip />
+ <!-- no translation found for enable_explore_by_touch_warning_message (2708199672852373195) -->
+ <skip />
<string name="oneMonthDurationPast" msgid="7396384508953779925">"pred 1 mesiacom"</string>
<string name="beforeOneMonthDurationPast" msgid="909134546836499826">"Viac ako pred 1 mesiacom"</string>
<plurals name="num_seconds_ago">
@@ -1119,6 +1127,10 @@
<string name="configure_input_methods" msgid="9091652157722495116">"Nastavenie metód vstupu"</string>
<string name="use_physical_keyboard" msgid="6203112478095117625">"Fyzická klávesnica"</string>
<string name="hardware" msgid="7517821086888990278">"Hardvér"</string>
+ <!-- no translation found for select_keyboard_layout_notification_title (1407367017263030773) -->
+ <skip />
+ <!-- no translation found for select_keyboard_layout_notification_message (4465907700449257063) -->
+ <skip />
<string name="fast_scroll_alphabet" msgid="5433275485499039199">" AÁÄBCČDĎDZDŽEÉFGHCHIÍJKLĽMNŇOÓÔPRŔSŠTŤUÚVWXYÝZŽ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="candidates_style" msgid="4333913089637062257"><u>"kandidáti"</u></string>
@@ -1312,5 +1324,6 @@
<string name="launchBrowserDefault" msgid="2057951947297614725">"Spustiť prehliadač?"</string>
<string name="SetupCallDefault" msgid="5834948469253758575">"Prijať hovor?"</string>
<string name="activity_resolver_use_always" msgid="8017770747801494933">"Vždy"</string>
- <string name="activity_resolver_use_once" msgid="405646673463328329">"Len raz"</string>
+ <!-- no translation found for activity_resolver_use_once (2404644797149173758) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml
index 32a0a22..2e019d4 100644
--- a/core/res/res/values-sl/strings.xml
+++ b/core/res/res/values-sl/strings.xml
@@ -317,6 +317,8 @@
<string name="permdesc_readInputState" msgid="8387754901688728043">"Programu omogoča spremljanje tipk, ki jih pritisnete med interakcijo z drugim programom (na primer vnos gesla). Navadni programi tega nikoli ne potrebujejo."</string>
<string name="permlab_bindInputMethod" msgid="3360064620230515776">"povezovanje z načinom vnosa"</string>
<string name="permdesc_bindInputMethod" msgid="3250440322807286331">"Lastniku omogoča, da se poveže z vmesnikom načina vnosa najvišje ravni. Tega nikoli ni treba uporabiti za navadne programe."</string>
+ <string name="permlab_bindAccessibilityService" msgid="5357733942556031593">"povezovanje s storitvijo za ljudi s posebnimi potrebami"</string>
+ <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Lastniku omogoča povezovanje z vmesnikom najvišje ravni storitve za ljudi s posebnimi potrebami. Tega nikoli ni treba uporabiti za navadne aplikacije."</string>
<string name="permlab_bindTextService" msgid="7358378401915287938">"poveži z besedilno storitvijo"</string>
<string name="permdesc_bindTextService" msgid="8151968910973998670">"Dovoljuje, da se lastnik poveže z vmesnikom besedilne storitve najvišje ravni (npr. SpellCheckerService). Tega nikoli ni treba uporabiti za navadne programe."</string>
<string name="permlab_bindVpnService" msgid="4708596021161473255">"povezava s storitvijo navideznega zasebnega omrežja"</string>
@@ -853,6 +855,12 @@
<string name="searchview_description_clear" msgid="1330281990951833033">"Izbris poizvedbe"</string>
<string name="searchview_description_submit" msgid="2688450133297983542">"Pošlji poizvedbo"</string>
<string name="searchview_description_voice" msgid="2453203695674994440">"Glasovno iskanje"</string>
+ <!-- no translation found for enable_explore_by_touch_warning_title (7460694070309730149) -->
+ <skip />
+ <!-- no translation found for enable_explore_by_touch_warning_message (8655887539089910577) -->
+ <skip />
+ <!-- no translation found for enable_explore_by_touch_warning_message (2708199672852373195) -->
+ <skip />
<string name="oneMonthDurationPast" msgid="7396384508953779925">"Pred 1 mesecem"</string>
<string name="beforeOneMonthDurationPast" msgid="909134546836499826">"Pred več kot 1 mesecem"</string>
<plurals name="num_seconds_ago">
@@ -1119,6 +1127,10 @@
<string name="configure_input_methods" msgid="9091652157722495116">"Nastavi načine vnosa"</string>
<string name="use_physical_keyboard" msgid="6203112478095117625">"Fizična tipkovnica"</string>
<string name="hardware" msgid="7517821086888990278">"Strojna oprema"</string>
+ <!-- no translation found for select_keyboard_layout_notification_title (1407367017263030773) -->
+ <skip />
+ <!-- no translation found for select_keyboard_layout_notification_message (4465907700449257063) -->
+ <skip />
<string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="candidates_style" msgid="4333913089637062257"><u>"kandidati"</u></string>
@@ -1312,5 +1324,6 @@
<string name="launchBrowserDefault" msgid="2057951947297614725">"Ali želite odpreti brskalnik?"</string>
<string name="SetupCallDefault" msgid="5834948469253758575">"Ali želite sprejeti klic?"</string>
<string name="activity_resolver_use_always" msgid="8017770747801494933">"Vedno"</string>
- <string name="activity_resolver_use_once" msgid="405646673463328329">"Samo tokrat"</string>
+ <!-- no translation found for activity_resolver_use_once (2404644797149173758) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml
index 3b416fe..6f067a1 100644
--- a/core/res/res/values-sr/strings.xml
+++ b/core/res/res/values-sr/strings.xml
@@ -317,6 +317,8 @@
<string name="permdesc_readInputState" msgid="8387754901688728043">"Дозвољава апликацији да види које тастере притискате чак и док радите у некој другој апликацији (нпр. када уносите лозинку). Уобичајене апликације никада не би требало да је користе."</string>
<string name="permlab_bindInputMethod" msgid="3360064620230515776">"обавезивање на методу уноса"</string>
<string name="permdesc_bindInputMethod" msgid="3250440322807286331">"Омогућава да се власник обавеже на интерфејс методе уноса највишег нивоа. Уобичајене апликације никада не би требало да је користе."</string>
+ <string name="permlab_bindAccessibilityService" msgid="5357733942556031593">"повезивање са услугом приступачности"</string>
+ <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Дозвољава власнику да се повеже са интерфејсом услуге приступачности највишег нивоа. Уобичајене апликације никада не би требало да је користе."</string>
<string name="permlab_bindTextService" msgid="7358378401915287938">"обавезивање на текстуалну услугу"</string>
<string name="permdesc_bindTextService" msgid="8151968910973998670">"Омогућава власнику да се обавеже на интерфејс текстуалне услуге највишег нивоа (нпр. SpellCheckerService). Обичне апликације никада не би требало да је користе."</string>
<string name="permlab_bindVpnService" msgid="4708596021161473255">"везивање за VPN услугу"</string>
@@ -853,6 +855,12 @@
<string name="searchview_description_clear" msgid="1330281990951833033">"Обриши упит"</string>
<string name="searchview_description_submit" msgid="2688450133297983542">"Пошаљи упит"</string>
<string name="searchview_description_voice" msgid="2453203695674994440">"Гласовна претрага"</string>
+ <!-- no translation found for enable_explore_by_touch_warning_title (7460694070309730149) -->
+ <skip />
+ <!-- no translation found for enable_explore_by_touch_warning_message (8655887539089910577) -->
+ <skip />
+ <!-- no translation found for enable_explore_by_touch_warning_message (2708199672852373195) -->
+ <skip />
<string name="oneMonthDurationPast" msgid="7396384508953779925">"Пре месец дана"</string>
<string name="beforeOneMonthDurationPast" msgid="909134546836499826">"Пре месец дана"</string>
<plurals name="num_seconds_ago">
@@ -1119,6 +1127,10 @@
<string name="configure_input_methods" msgid="9091652157722495116">"Подеси методе уноса"</string>
<string name="use_physical_keyboard" msgid="6203112478095117625">"Физичка тастатура"</string>
<string name="hardware" msgid="7517821086888990278">"Хардвер"</string>
+ <!-- no translation found for select_keyboard_layout_notification_title (1407367017263030773) -->
+ <skip />
+ <!-- no translation found for select_keyboard_layout_notification_message (4465907700449257063) -->
+ <skip />
<string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="candidates_style" msgid="4333913089637062257"><u>"кандидати"</u></string>
@@ -1312,5 +1324,6 @@
<string name="launchBrowserDefault" msgid="2057951947297614725">"Желите ли да покренете прегледач?"</string>
<string name="SetupCallDefault" msgid="5834948469253758575">"Желите ли да прихватите позив?"</string>
<string name="activity_resolver_use_always" msgid="8017770747801494933">"Увек"</string>
- <string name="activity_resolver_use_once" msgid="405646673463328329">"Само једном"</string>
+ <!-- no translation found for activity_resolver_use_once (2404644797149173758) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml
index f91db69..c9b7e2b 100644
--- a/core/res/res/values-sv/strings.xml
+++ b/core/res/res/values-sv/strings.xml
@@ -317,6 +317,8 @@
<string name="permdesc_readInputState" msgid="8387754901688728043">"Tillåter att appen övervakar knapparna som du trycker på, till och med när du använder andra appar (till exempel när du anger ett lösenord). Ska inte behövas för vanliga appar."</string>
<string name="permlab_bindInputMethod" msgid="3360064620230515776">"binda till en metod för indata"</string>
<string name="permdesc_bindInputMethod" msgid="3250440322807286331">"Innehavaren tillåts att binda till den översta nivåns gränssnitt för en inmatningsmetod. Ska inte behövas för vanliga appar."</string>
+ <string name="permlab_bindAccessibilityService" msgid="5357733942556031593">"bind till en tillgänglighetstjänst"</string>
+ <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Innehavaren tillåts att binda till den översta nivåns gränssnitt för en tillgänglighetstjänst. Ska inte behövas för vanliga appar."</string>
<string name="permlab_bindTextService" msgid="7358378401915287938">"bind till en texttjänst"</string>
<string name="permdesc_bindTextService" msgid="8151968910973998670">"Tillåter innehavaren att binda mot den högsta gränssnittsnivån i en texttjänst (t.ex. SpellCheckerService). Bör aldrig behövas för normala appar."</string>
<string name="permlab_bindVpnService" msgid="4708596021161473255">"bind till en VPN-tjänst"</string>
@@ -853,6 +855,12 @@
<string name="searchview_description_clear" msgid="1330281990951833033">"Ta bort frågan"</string>
<string name="searchview_description_submit" msgid="2688450133297983542">"Skicka fråga"</string>
<string name="searchview_description_voice" msgid="2453203695674994440">"Röstsökning"</string>
+ <!-- no translation found for enable_explore_by_touch_warning_title (7460694070309730149) -->
+ <skip />
+ <!-- no translation found for enable_explore_by_touch_warning_message (8655887539089910577) -->
+ <skip />
+ <!-- no translation found for enable_explore_by_touch_warning_message (2708199672852373195) -->
+ <skip />
<string name="oneMonthDurationPast" msgid="7396384508953779925">"för 1 månad sedan"</string>
<string name="beforeOneMonthDurationPast" msgid="909134546836499826">"För mer än en månad sedan"</string>
<plurals name="num_seconds_ago">
@@ -1119,6 +1127,10 @@
<string name="configure_input_methods" msgid="9091652157722495116">"Konfigurera inmatningsmetoder"</string>
<string name="use_physical_keyboard" msgid="6203112478095117625">"Fysiskt tangentbord"</string>
<string name="hardware" msgid="7517821086888990278">"Maskinvara"</string>
+ <!-- no translation found for select_keyboard_layout_notification_title (1407367017263030773) -->
+ <skip />
+ <!-- no translation found for select_keyboard_layout_notification_message (4465907700449257063) -->
+ <skip />
<string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="candidates_style" msgid="4333913089637062257"><u>"kandidater"</u></string>
@@ -1312,5 +1324,6 @@
<string name="launchBrowserDefault" msgid="2057951947297614725">"Vill du öppna webbläsaren?"</string>
<string name="SetupCallDefault" msgid="5834948469253758575">"Vill du ta emot samtal?"</string>
<string name="activity_resolver_use_always" msgid="8017770747801494933">"Alltid"</string>
- <string name="activity_resolver_use_once" msgid="405646673463328329">"Bara den här gången"</string>
+ <!-- no translation found for activity_resolver_use_once (2404644797149173758) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml
index 1904de4..35079c5 100644
--- a/core/res/res/values-sw/strings.xml
+++ b/core/res/res/values-sw/strings.xml
@@ -317,6 +317,8 @@
<string name="permdesc_readInputState" msgid="8387754901688728043">"Inaruhusu programu kuangalia vibonye unavyo bonyeza hata wakati unapo shirikiana na programu nyingine (kama vile kuweka neno). Kamwe isihitajike na programu za kawaida."</string>
<string name="permlab_bindInputMethod" msgid="3360064620230515776">"funganisha kwa mbinu ya uingizaji"</string>
<string name="permdesc_bindInputMethod" msgid="3250440322807286331">"Inaruhusu mmiliki kushurutisha kwenye kusano ya kiwango cha juu ya mbinu ya ingizo. Haipaswi kuhitajika kwa programu za kawaida."</string>
+ <string name="permlab_bindAccessibilityService" msgid="5357733942556031593">"funga kwa huduma ya afikiaji"</string>
+ <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Inamuruhusu mmiliki kufunga kipengee kinachojitokeza katika nyanja mbalimbali za kiwango cha juu cha huduma ya afikiaji. Hapaswi kuhitajika kwa programu za kawaida."</string>
<string name="permlab_bindTextService" msgid="7358378401915287938">"Imefungwa kwa huduma ya maandishi"</string>
<string name="permdesc_bindTextService" msgid="8151968910973998670">"Inaruhusu kishikiliaji kushurutisha kusano ya kiwango cha juu ya huduma ya matini(k.m.SpellCheckerService). Haipaswi kuhitajika kwa programu za kawaida."</string>
<string name="permlab_bindVpnService" msgid="4708596021161473255">"funga kwa huduma ya VPN"</string>
@@ -853,6 +855,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="oneMonthDurationPast" msgid="7396384508953779925">"Mwezi 1 uliopita"</string>
<string name="beforeOneMonthDurationPast" msgid="909134546836499826">"Kabla ya mwezi 1 uliopita"</string>
<plurals name="num_seconds_ago">
@@ -1081,7 +1086,7 @@
<string name="date_time_set" msgid="5777075614321087758">"Weka"</string>
<string name="date_time_done" msgid="2507683751759308828">"Imekamilika"</string>
<string name="perms_new_perm_prefix" msgid="8257740710754301407"><font size="12" fgcolor="#ff900000">" MPYA: "</font></string>
- <string name="perms_description_app" msgid="5139836143293299417">"Zinatolewa na <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
+ <string name="perms_description_app" msgid="5139836143293299417">"Imetolewa na <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
<string name="no_permissions" msgid="7283357728219338112">"Hakuna vibali vinavyohitajika"</string>
<string name="usb_storage_activity_title" msgid="4465055157209648641">"Hifadhi kubwa ya USB"</string>
<string name="usb_storage_title" msgid="5901459041398751495">"USB imeunganishwa"</string>
@@ -1119,6 +1124,8 @@
<string name="configure_input_methods" msgid="9091652157722495116">"Weka mbinu za ingizo"</string>
<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="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>
@@ -1312,5 +1319,5 @@
<string name="launchBrowserDefault" msgid="2057951947297614725">"Zindua Kivinjari?"</string>
<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="405646673463328329">"Mara Moja tu"</string>
+ <string name="activity_resolver_use_once" msgid="2404644797149173758">"Mara moja tu"</string>
</resources>
diff --git a/core/res/res/values-sw600dp/config.xml b/core/res/res/values-sw600dp/config.xml
index b54e9d1..1486d9c 100644
--- a/core/res/res/values-sw600dp/config.xml
+++ b/core/res/res/values-sw600dp/config.xml
@@ -20,9 +20,6 @@
<!-- These resources are around just to allow their values to be customized
for different hardware and product builds. -->
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <!-- see comment in values/config.xml -->
- <integer name="config_longPressOnPowerBehavior">2</integer>
-
<!-- Enable lockscreen rotation -->
<bool name="config_enableLockScreenRotation">true</bool>
diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml
index 17dcf64..34e4433 100644
--- a/core/res/res/values-th/strings.xml
+++ b/core/res/res/values-th/strings.xml
@@ -317,6 +317,8 @@
<string name="permdesc_readInputState" msgid="8387754901688728043">"อนุญาตให้แอปพลิเคชันดูแป้นที่คุณกดแม้ในขณะที่กำลังโต้ตอบกับแอปพลิเคชันอื่น (เช่น ขณะพิมพ์รหัสผ่าน) ไม่ควรต้องใช้สำหรับแอปพลิเคชันทั่วไป"</string>
<string name="permlab_bindInputMethod" msgid="3360064620230515776">"เชื่อมโยงกับวิธีป้อนข้อมูล"</string>
<string name="permdesc_bindInputMethod" msgid="3250440322807286331">"อนุญาตให้ผู้ใช้เชื่อมโยงกับส่วนติดต่อผู้ใช้ระดับสูงสุดของวิธีการป้อนข้อมูล ไม่ควรต้องใช้สำหรับแอปพลิเคชันทั่วไป"</string>
+ <string name="permlab_bindAccessibilityService" msgid="5357733942556031593">"เชื่อมโยงกับบริการการเข้าถึง"</string>
+ <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"อนุญาตให้เจ้าของเชื่อมโยงกับส่วนติดต่อระดับบนสุดของบริการการเข้าถึง ซึ่งแอปพลิเคชันทั่วไปไม่จำเป็นต้องใช้"</string>
<string name="permlab_bindTextService" msgid="7358378401915287938">"เชื่อมโยงกับบริการข้อความ"</string>
<string name="permdesc_bindTextService" msgid="8151968910973998670">"อนุญาตให้ผู้ใช้เชื่อมโยงกับส่วนติดต่อผู้ใช้ระดับสูงสุดของบริการข้อความ (เช่น บริการเครื่องตรวจตัวสะกด) ไม่ควรต้องใช้สำหรับแอปพลิเคชันทั่วไป"</string>
<string name="permlab_bindVpnService" msgid="4708596021161473255">"เชื่อมโยงกับบริการ VPN"</string>
@@ -853,6 +855,9 @@
<string name="searchview_description_clear" msgid="1330281990951833033">"ล้างข้อความค้นหา"</string>
<string name="searchview_description_submit" msgid="2688450133297983542">"ส่งข้อความค้นหา"</string>
<string name="searchview_description_voice" msgid="2453203695674994440">"ค้นหาด้วยเสียง"</string>
+ <string name="enable_explore_by_touch_warning_title" msgid="7460694070309730149">"เปิดใช้งาน \"สำรวจโดยการแตะ\" หรือไม่"</string>
+ <string name="enable_explore_by_touch_warning_message" product="tablet" msgid="8655887539089910577">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> ต้องการเปิดใช้งาน \"สำรวจโดยการแตะ\" เมื่อเปิดใช้งานแล้ว คุณสามารถฟังหรือดูคำอธิบายของสิ่งที่อยู่ใต้นิ้วข​​องคุณ หรือใช้ท่าทางสัมผัสต่างๆ เพื่อโต้ตอบกับแท็บเล็ตได้"</string>
+ <string name="enable_explore_by_touch_warning_message" product="default" msgid="2708199672852373195">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> ต้องการเปิดใช้งาน \"สำรวจโดยการแตะ\" เมื่อเปิดใช้งานแล้ว คุณสามารถฟังหรือดูคำอธิบายของสิ่งที่อยู่ใต้นิ้วข​​องคุณ หรือใช้ท่าทางสัมผัสต่างๆ เพื่อโต้ตอบกับโทรศัพท์ได้"</string>
<string name="oneMonthDurationPast" msgid="7396384508953779925">"1 เดือนที่ผ่านมา"</string>
<string name="beforeOneMonthDurationPast" msgid="909134546836499826">"ก่อน 1 เดือนที่แล้ว"</string>
<plurals name="num_seconds_ago">
@@ -1119,6 +1124,8 @@
<string name="configure_input_methods" msgid="9091652157722495116">"ตั้งค่าวิธีการป้อนข้อมูล"</string>
<string name="use_physical_keyboard" msgid="6203112478095117625">"แป้นพิมพ์บนเครื่อง"</string>
<string name="hardware" msgid="7517821086888990278">"ฮาร์ดแวร์"</string>
+ <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"เลือกรูปแบบแป้นพิมพ์"</string>
+ <string name="select_keyboard_layout_notification_message" msgid="4465907700449257063">"แตะเพื่อเลือกรูปแบบแป้นพิมพ์"</string>
<string name="fast_scroll_alphabet" msgid="5433275485499039199">" กขฃคฅฆงจฉชซฌญฎฏฐฑฒณดตถทธนบปผฝพฟภมยรลวศษสหฬอฮ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" กขฃคฅฆงจฉชซฌญฎฏฐฑฒณดตถทธนบปผฝพฟภมยรลวศษสหฬอฮ"</string>
<string name="candidates_style" msgid="4333913089637062257"><u>"ตัวเลือก"</u></string>
@@ -1312,5 +1319,5 @@
<string name="launchBrowserDefault" msgid="2057951947297614725">"เปิดเบราว์เซอร์หรือไม่"</string>
<string name="SetupCallDefault" msgid="5834948469253758575">"รับสายหรือไม่"</string>
<string name="activity_resolver_use_always" msgid="8017770747801494933">"ทุกครั้ง"</string>
- <string name="activity_resolver_use_once" msgid="405646673463328329">"เพียงแค่ครั้งเดียว"</string>
+ <string name="activity_resolver_use_once" msgid="2404644797149173758">"เฉพาะครั้งนี้"</string>
</resources>
diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml
index 70f8143..666d131 100644
--- a/core/res/res/values-tl/strings.xml
+++ b/core/res/res/values-tl/strings.xml
@@ -317,6 +317,8 @@
<string name="permdesc_readInputState" msgid="8387754901688728043">"Pinapayagan ang app na tingnan ang mga key na iyong pinipindot kahit na nakikipag-ugnayan sa isa pang app (gaya ng pag-type ng password). Hindi kailanman dapat na kailanganin para sa normal na apps."</string>
<string name="permlab_bindInputMethod" msgid="3360064620230515776">"sumailalim sa isang pamamaraan ng pag-input"</string>
<string name="permdesc_bindInputMethod" msgid="3250440322807286331">"Pinapayagan ang may-hawak na sumailalim sa nangungunang interface ng pamamaraan ng pag-input. Hindi kailanman dapat na kailanganin para sa normal na apps."</string>
+ <string name="permlab_bindAccessibilityService" msgid="5357733942556031593">"sumailalim sa isang serbisyo sa accessibility"</string>
+ <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Binibigyang-daan ang may-ari na sumailalim sa nasa nangungunang antas na interface ng isang serbisyo sa accessibility. Hindi dapat kailanman kailanganin para sa normal na apps."</string>
<string name="permlab_bindTextService" msgid="7358378401915287938">"sumailalim sa serbisyo ng teksto"</string>
<string name="permdesc_bindTextService" msgid="8151968910973998670">"Pinapayagan ang may-hawak na sumailalim sa nangungunang antas na interface (hal. SpellCheckerService). Hindi kailanman dapat na kailanganin para sa normal na apps."</string>
<string name="permlab_bindVpnService" msgid="4708596021161473255">"sumailalim sa isang serbisyo ng VPN"</string>
@@ -853,6 +855,9 @@
<string name="searchview_description_clear" msgid="1330281990951833033">"I-clear ang query"</string>
<string name="searchview_description_submit" msgid="2688450133297983542">"Isumite ang query"</string>
<string name="searchview_description_voice" msgid="2453203695674994440">"Paghahanap gamit ang boses"</string>
+ <string name="enable_explore_by_touch_warning_title" msgid="7460694070309730149">"Paganahin ang Galugad sa pagpindot?"</string>
+ <string name="enable_explore_by_touch_warning_message" product="tablet" msgid="8655887539089910577">"Nais paganahin ng <xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> ang Galugarin sa pamamagitan ng pagpindot. Kapag naka-on ang Galugarin sa pamamagitan ng pagpindot, maaari mong marinig o makita ang mga paglalarawan ng nasa ilalim ng iyong daliri o maaari kang magsagawa ng mga galaw upang makipag-ugnayan sa tablet."</string>
+ <string name="enable_explore_by_touch_warning_message" product="default" msgid="2708199672852373195">"Nais paganahin ng <xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> ang Galugarin sa pamamagitan ng pagpindot. Kapag naka-on ang Galugarin sa pamamagitan ng pagpindot, maaari mong marinig o makita ang mga paglalarawan ng nasa ilalim ng iyong daliri o maaari kang magsagawa ng mga galaw upang makipag-ugnayan sa telepono."</string>
<string name="oneMonthDurationPast" msgid="7396384508953779925">"1 buwan ang nakalipas"</string>
<string name="beforeOneMonthDurationPast" msgid="909134546836499826">"Bago ang nakalipas na 1 buwan"</string>
<plurals name="num_seconds_ago">
@@ -1119,6 +1124,8 @@
<string name="configure_input_methods" msgid="9091652157722495116">"I-set up paraan ng pag-input"</string>
<string name="use_physical_keyboard" msgid="6203112478095117625">"Aktwal na keyboard"</string>
<string name="hardware" msgid="7517821086888990278">"Hardware"</string>
+ <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"Pumili ng layout ng keyboard"</string>
+ <string name="select_keyboard_layout_notification_message" msgid="4465907700449257063">"Pindutin upang pumili ng layout ng keyboard."</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>"mga kandidato"</u></string>
@@ -1312,5 +1319,5 @@
<string name="launchBrowserDefault" msgid="2057951947297614725">"Ilunsad ang Browser?"</string>
<string name="SetupCallDefault" msgid="5834948469253758575">"Tanggapin ang tawag?"</string>
<string name="activity_resolver_use_always" msgid="8017770747801494933">"Palagi"</string>
- <string name="activity_resolver_use_once" msgid="405646673463328329">"Isang Beses Lang"</string>
+ <string name="activity_resolver_use_once" msgid="2404644797149173758">"Isang beses lang"</string>
</resources>
diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml
index 9222823..c9ee115 100644
--- a/core/res/res/values-tr/strings.xml
+++ b/core/res/res/values-tr/strings.xml
@@ -317,6 +317,8 @@
<string name="permdesc_readInputState" msgid="8387754901688728043">"Uygulamaya, başka bir uygulama ile etkileşim halindeyken dahi (örneğin, şifre yazarken) bastığınız tuşları izleme izni verir. Normal uygulamalar için gerekli değildir."</string>
<string name="permlab_bindInputMethod" msgid="3360064620230515776">"bir giriş yöntemine bağla"</string>
<string name="permdesc_bindInputMethod" msgid="3250440322807286331">"Cihazın sahibine, bir giriş yönteminin en üst düzey arayüzüne bağlanma izni verir. Normal uygulamalarda hiçbir zaman gerek duyulmaz."</string>
+ <string name="permlab_bindAccessibilityService" msgid="5357733942556031593">"erişilebilirlik hizmetine bağlan"</string>
+ <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"İzin sahibine bir erişilebilirlik hizmetinin en üst düzey arayüzüne bağlanma izni verir. Normal uygulamalarda hiçbir zaman gerek duyulmaz."</string>
<string name="permlab_bindTextService" msgid="7358378401915287938">"kısa mesaj hizmetine bağla"</string>
<string name="permdesc_bindTextService" msgid="8151968910973998670">"Cihazın sahibine, bir metin hizmetinin (ör. SpellCheckerService) en üst düzey arayüzüne bağlanma izni verir. Normal uygulamalarda hiçbir zaman gerekmez."</string>
<string name="permlab_bindVpnService" msgid="4708596021161473255">"VPN hizmetine bağlan"</string>
@@ -853,6 +855,12 @@
<string name="searchview_description_clear" msgid="1330281990951833033">"Sorguyu temizle"</string>
<string name="searchview_description_submit" msgid="2688450133297983542">"Sorguyu gönder"</string>
<string name="searchview_description_voice" msgid="2453203695674994440">"Sesli arama"</string>
+ <!-- no translation found for enable_explore_by_touch_warning_title (7460694070309730149) -->
+ <skip />
+ <!-- no translation found for enable_explore_by_touch_warning_message (8655887539089910577) -->
+ <skip />
+ <!-- no translation found for enable_explore_by_touch_warning_message (2708199672852373195) -->
+ <skip />
<string name="oneMonthDurationPast" msgid="7396384508953779925">"1 ay önce"</string>
<string name="beforeOneMonthDurationPast" msgid="909134546836499826">"1 ay önce"</string>
<plurals name="num_seconds_ago">
@@ -1119,6 +1127,10 @@
<string name="configure_input_methods" msgid="9091652157722495116">"Giriş yöntemlerini ayarla"</string>
<string name="use_physical_keyboard" msgid="6203112478095117625">"Fiziksel klavye"</string>
<string name="hardware" msgid="7517821086888990278">"Donanım"</string>
+ <!-- no translation found for select_keyboard_layout_notification_title (1407367017263030773) -->
+ <skip />
+ <!-- no translation found for select_keyboard_layout_notification_message (4465907700449257063) -->
+ <skip />
<string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="candidates_style" msgid="4333913089637062257"><u>"adaylar"</u></string>
@@ -1312,5 +1324,6 @@
<string name="launchBrowserDefault" msgid="2057951947297614725">"Tarayıcı Başlatılsın mı?"</string>
<string name="SetupCallDefault" msgid="5834948469253758575">"Çağrı kabul edilsin mi?"</string>
<string name="activity_resolver_use_always" msgid="8017770747801494933">"Her zaman"</string>
- <string name="activity_resolver_use_once" msgid="405646673463328329">"Sadece Bir Defa"</string>
+ <!-- no translation found for activity_resolver_use_once (2404644797149173758) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml
index 150f728..3e3b506 100644
--- a/core/res/res/values-uk/strings.xml
+++ b/core/res/res/values-uk/strings.xml
@@ -317,6 +317,8 @@
<string name="permdesc_readInputState" msgid="8387754901688728043">"Дозволяє програмі бачити клавіші, які ви натискаєте, навіть під час взаємодії з іншою програмою (як-от під час введення пароля). Ніколи не застосовується для звичайних програм."</string>
<string name="permlab_bindInputMethod" msgid="3360064620230515776">"прив\'яз. до методу введ."</string>
<string name="permdesc_bindInputMethod" msgid="3250440322807286331">"Дозволяє власнику прив’язуватися до інтерфейсу верхнього рівня методу введення. Ніколи не застосовується для звичайних програм."</string>
+ <string name="permlab_bindAccessibilityService" msgid="5357733942556031593">"прив’язуватися до служби доступності"</string>
+ <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Дозволяє власникові прив’язуватися до інтерфейсу верхнього рівня служби доступності. Ніколи не застосовується для звичайних програм."</string>
<string name="permlab_bindTextService" msgid="7358378401915287938">"прив’язати до текстової служби"</string>
<string name="permdesc_bindTextService" msgid="8151968910973998670">"Дозволяє власникові прив’язуватися до інтерфейсу верхнього рівня текстової служби (напр. SpellCheckerService). Ніколи не застосовується для звичайних програм."</string>
<string name="permlab_bindVpnService" msgid="4708596021161473255">"прив’язуватися до служби VPN"</string>
@@ -853,6 +855,9 @@
<string name="searchview_description_clear" msgid="1330281990951833033">"Очистити запит"</string>
<string name="searchview_description_submit" msgid="2688450133297983542">"Наіслати запит"</string>
<string name="searchview_description_voice" msgid="2453203695674994440">"Голосовий пошук"</string>
+ <string name="enable_explore_by_touch_warning_title" msgid="7460694070309730149">"Увімкнути дослідження дотиком?"</string>
+ <string name="enable_explore_by_touch_warning_message" product="tablet" msgid="8655887539089910577">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> хоче ввімкнути функцію дослідження дотиком. Увімкнувши функцію дослідження дотиком, можна чути або бачити опис елемента, розташованого під вашим пальцем, або виконувати жести для взаємодії з планшетним ПК."</string>
+ <string name="enable_explore_by_touch_warning_message" product="default" msgid="2708199672852373195">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> хоче ввімкнути функцію дослідження дотиком. Увімкнувши функцію дослідження дотиком, можна чути або бачити опис елемента, розташованого під вашим пальцем, або виконувати жести для взаємодії з телефоном."</string>
<string name="oneMonthDurationPast" msgid="7396384508953779925">"1 міс. тому"</string>
<string name="beforeOneMonthDurationPast" msgid="909134546836499826">"Раніше 1 місяця тому"</string>
<plurals name="num_seconds_ago">
@@ -1119,6 +1124,8 @@
<string name="configure_input_methods" msgid="9091652157722495116">"Налаштувати методи введення"</string>
<string name="use_physical_keyboard" msgid="6203112478095117625">"Фізична клавіатура"</string>
<string name="hardware" msgid="7517821086888990278">"Обладнання"</string>
+ <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"Виберіть розкладку клавіатури"</string>
+ <string name="select_keyboard_layout_notification_message" msgid="4465907700449257063">"Торкніться, щоб вибрати розкладку клавіатури."</string>
<string name="fast_scroll_alphabet" msgid="5433275485499039199">" АБВГҐДЕЄЖЗИІЇЙКЛМНОПРСТУФХЦЧШЩЬЮЯ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789АБВГҐДЕЄЖЗИІЇЙКЛМНОПРСТУФХЦЧШЩЬЮЯ"</string>
<string name="candidates_style" msgid="4333913089637062257"><u>"кандидати"</u></string>
@@ -1312,5 +1319,5 @@
<string name="launchBrowserDefault" msgid="2057951947297614725">"Запустити веб-переглядач?"</string>
<string name="SetupCallDefault" msgid="5834948469253758575">"Прийняти виклик?"</string>
<string name="activity_resolver_use_always" msgid="8017770747801494933">"Завжди"</string>
- <string name="activity_resolver_use_once" msgid="405646673463328329">"Лише один раз"</string>
+ <string name="activity_resolver_use_once" msgid="2404644797149173758">"Лише цього разу"</string>
</resources>
diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml
index 542f048..af89a2d 100644
--- a/core/res/res/values-vi/strings.xml
+++ b/core/res/res/values-vi/strings.xml
@@ -177,8 +177,8 @@
<string name="permgroupdesc_network" msgid="4478299413241861987">"Truy cập các tính năng mạng khác nhau."</string>
<string name="permgrouplab_bluetoothNetwork" msgid="1585403544162128109">"Bluetooth"</string>
<string name="permgroupdesc_bluetoothNetwork" msgid="5625288577164282391">"Truy cập vào các thiết bị và mạng thông qua Bluetooth."</string>
- <string name="permgrouplab_shortrangeNetwork" msgid="130808676377486118">"Mạng tầm ngắn"</string>
- <string name="permgroupdesc_shortrangeNetwork" msgid="1884069062653436007">"Truy cập vào các thiết bị thông qua mạng tầm ngắn như NFC."</string>
+ <string name="permgrouplab_shortrangeNetwork" msgid="130808676377486118">"Mạng phạm vi ngắn"</string>
+ <string name="permgroupdesc_shortrangeNetwork" msgid="1884069062653436007">"Truy cập vào các thiết bị thông qua mạng phạm vi ngắn như NFC."</string>
<string name="permgrouplab_audioSettings" msgid="8329261670151871235">"Cài đặt âm thanh"</string>
<string name="permgroupdesc_audioSettings" msgid="2641515403347568130">"Thay đổi cài đặt âm thanh."</string>
<string name="permgrouplab_affectsBattery" msgid="6209246653424798033">"Ảnh hưởng tới pin"</string>
@@ -317,6 +317,8 @@
<string name="permdesc_readInputState" msgid="8387754901688728043">"Cho phép ứng dụng xem các phím bạn nhấn ngay cả khi tương tác với ứng dụng khác (chẳng hạn như nhập mật khẩu). Không cần thiết cho các ứng dụng thông thường."</string>
<string name="permlab_bindInputMethod" msgid="3360064620230515776">"liên kết với phương thức nhập"</string>
<string name="permdesc_bindInputMethod" msgid="3250440322807286331">"Cho phép chủ sở hữu liên kết với giao diện cấp cao nhất của phương thức nhập. Không cần thiết cho các ứng dụng thông thường."</string>
+ <string name="permlab_bindAccessibilityService" msgid="5357733942556031593">"liên kết với dịch vụ truy cập"</string>
+ <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Cho phép chủ sở hữu liên kết với giao diện cấp cao nhất của dịch vụ truy cập. Không cần thiết cho các ứng dụng thông thường."</string>
<string name="permlab_bindTextService" msgid="7358378401915287938">"liên kết với dịch vụ văn bản"</string>
<string name="permdesc_bindTextService" msgid="8151968910973998670">"Cho phép chủ sở hữu liên kết với giao diện cấp cao nhất của dịch vụ văn bản (ví dụ: SpellCheckerService). Không cần thiết cho các ứng dụng thông thường."</string>
<string name="permlab_bindVpnService" msgid="4708596021161473255">"liên kết với dịch vụ VPN"</string>
@@ -853,6 +855,9 @@
<string name="searchview_description_clear" msgid="1330281990951833033">"Xóa truy vấn"</string>
<string name="searchview_description_submit" msgid="2688450133297983542">"Gửi truy vấn"</string>
<string name="searchview_description_voice" msgid="2453203695674994440">"Tìm kiếm bằng giọng nói"</string>
+ <string name="enable_explore_by_touch_warning_title" msgid="7460694070309730149">"Bật Khám phá bằng cách chạm?"</string>
+ <string name="enable_explore_by_touch_warning_message" product="tablet" msgid="8655887539089910577">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> muốn bật Khám phá bằng cách chạm. Khi Khám phá bằng cách chạm được bật, bạn có thể nghe hoặc xem mô tả dưới ngón tay bạn hoặc thực hiện cử chỉ để tương tác với máy tính bảng."</string>
+ <string name="enable_explore_by_touch_warning_message" product="default" msgid="2708199672852373195">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> muốn bật Khám phá bằng cách chạm. Khi Khám phá bằng cách chạm được bật, bạn có thể nghe hoặc xem mô tả dưới ngón tay bạn hoặc thực hiện cử chỉ để tương tác với điện thoại."</string>
<string name="oneMonthDurationPast" msgid="7396384508953779925">"1 tháng trước"</string>
<string name="beforeOneMonthDurationPast" msgid="909134546836499826">"Trước 1 tháng trước"</string>
<plurals name="num_seconds_ago">
@@ -1119,6 +1124,8 @@
<string name="configure_input_methods" msgid="9091652157722495116">"Thiết lập phương thức nhập"</string>
<string name="use_physical_keyboard" msgid="6203112478095117625">"Bàn phím thực"</string>
<string name="hardware" msgid="7517821086888990278">"Phần cứng"</string>
+ <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"Chọn bố cục bàn phím"</string>
+ <string name="select_keyboard_layout_notification_message" msgid="4465907700449257063">"Chạm để chọn bố cục bàn phím."</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>"ứng viên"</u></string>
@@ -1311,6 +1318,6 @@
<string name="sending" msgid="3245653681008218030">"Đang gửi…"</string>
<string name="launchBrowserDefault" msgid="2057951947297614725">"Khởi chạy trình duyệt?"</string>
<string name="SetupCallDefault" msgid="5834948469253758575">"Chấp nhận cuộc gọi?"</string>
- <string name="activity_resolver_use_always" msgid="8017770747801494933">"Luôn bật"</string>
- <string name="activity_resolver_use_once" msgid="405646673463328329">"Chỉ một lần"</string>
+ <string name="activity_resolver_use_always" msgid="8017770747801494933">"Luôn chọn"</string>
+ <string name="activity_resolver_use_once" msgid="2404644797149173758">"Chỉ một lần"</string>
</resources>
diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml
index b2ba997..865761b 100644
--- a/core/res/res/values-zh-rCN/strings.xml
+++ b/core/res/res/values-zh-rCN/strings.xml
@@ -170,7 +170,7 @@
<string name="permgrouplab_personalInfo" msgid="3519163141070533474">"您的个人信息"</string>
<string name="permgroupdesc_personalInfo" msgid="8426453129788861338">"直接访问您存储在名片上的信息。"</string>
<string name="permgrouplab_socialInfo" msgid="5799096623412043791">"您的社交信息"</string>
- <string name="permgroupdesc_socialInfo" msgid="7129842457611643493">"直接访问与您的联系人和社交关系相关的信息。"</string>
+ <string name="permgroupdesc_socialInfo" msgid="7129842457611643493">"直接访问与您的联系人和社交人脉相关的信息。"</string>
<string name="permgrouplab_location" msgid="635149742436692049">"您的位置"</string>
<string name="permgroupdesc_location" msgid="5704679763124170100">"监视您的实际位置。"</string>
<string name="permgrouplab_network" msgid="5808983377727109831">"网络通信"</string>
@@ -185,10 +185,10 @@
<string name="permgroupdesc_affectsBattery" msgid="6441275320638916947">"使用耗电量较大的功能。"</string>
<string name="permgrouplab_calendar" msgid="5863508437783683902">"日历"</string>
<string name="permgroupdesc_calendar" msgid="5777534316982184416">"直接访问日历和活动。"</string>
- <string name="permgrouplab_dictionary" msgid="4148597128843641379">"读取用户字典"</string>
- <string name="permgroupdesc_dictionary" msgid="7921166355964764490">"读取用户字典中的字词。"</string>
- <string name="permgrouplab_writeDictionary" msgid="8090237702432576788">"写入用户字典"</string>
- <string name="permgroupdesc_writeDictionary" msgid="2711561994497361646">"将字词添加到用户字典。"</string>
+ <string name="permgrouplab_dictionary" msgid="4148597128843641379">"读取用户词典"</string>
+ <string name="permgroupdesc_dictionary" msgid="7921166355964764490">"读取用户词典中的字词。"</string>
+ <string name="permgrouplab_writeDictionary" msgid="8090237702432576788">"写入用户词典"</string>
+ <string name="permgroupdesc_writeDictionary" msgid="2711561994497361646">"将字词添加到用户词典。"</string>
<string name="permgrouplab_bookmarks" msgid="1949519673103968229">"书签和历史记录"</string>
<string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"直接访问书签和浏览器历史记录。"</string>
<string name="permgrouplab_deviceAlarms" msgid="6117704629728824101">"闹钟"</string>
@@ -196,9 +196,9 @@
<string name="permgrouplab_voicemail" msgid="4162237145027592133">"语音信箱"</string>
<string name="permgroupdesc_voicemail" msgid="2498403969862951393">"直接访问语音信箱。"</string>
<string name="permgrouplab_microphone" msgid="171539900250043464">"麦克风"</string>
- <string name="permgroupdesc_microphone" msgid="7106618286905738408">"直接访问麦克风以录制音频。"</string>
+ <string name="permgroupdesc_microphone" msgid="7106618286905738408">"直接使用麦克风以录制音频。"</string>
<string name="permgrouplab_camera" msgid="4820372495894586615">"相机"</string>
- <string name="permgroupdesc_camera" msgid="2933667372289567714">"直接访问相机以拍摄图片或视频。"</string>
+ <string name="permgroupdesc_camera" msgid="2933667372289567714">"直接使用相机以拍摄图片或视频。"</string>
<string name="permgrouplab_appInfo" msgid="8028789762634147725">"您的应用信息"</string>
<string name="permgroupdesc_appInfo" msgid="3950378538049625907">"能够影响设备上其他应用的行为。"</string>
<string name="permgrouplab_wallpaper" msgid="3850280158041175998">"壁纸"</string>
@@ -211,7 +211,7 @@
<string name="permgroupdesc_syncSettings" msgid="7603195265129031797">"访问同步设置。"</string>
<string name="permgrouplab_accounts" msgid="3359646291125325519">"您的帐户"</string>
<string name="permgroupdesc_accounts" msgid="4948732641827091312">"访问可用的帐户。"</string>
- <string name="permgrouplab_hardwareControls" msgid="7998214968791599326">"硬件控件"</string>
+ <string name="permgrouplab_hardwareControls" msgid="7998214968791599326">"硬件控制"</string>
<string name="permgroupdesc_hardwareControls" msgid="4357057861225462702">"直接访问手机上的硬件。"</string>
<string name="permgrouplab_phoneCalls" msgid="9067173988325865923">"手机通话"</string>
<string name="permgroupdesc_phoneCalls" msgid="7489701620446183770">"监管、记录和处理电话呼叫。"</string>
@@ -317,10 +317,12 @@
<string name="permdesc_readInputState" msgid="8387754901688728043">"允许应用记录您所按的键,包括与其他应用进行交互(如输入密码)时按的键。普通应用绝不需要此权限。"</string>
<string name="permlab_bindInputMethod" msgid="3360064620230515776">"绑定至输入法"</string>
<string name="permdesc_bindInputMethod" msgid="3250440322807286331">"允许用户绑定至输入法的顶级接口。普通应用绝不需要此权限。"</string>
+ <string name="permlab_bindAccessibilityService" msgid="5357733942556031593">"绑定至辅助服务"</string>
+ <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"允许应用绑定至辅助服务的顶级接口。普通应用绝不需要此权限。"</string>
<string name="permlab_bindTextService" msgid="7358378401915287938">"绑定至文字服务"</string>
<string name="permdesc_bindTextService" msgid="8151968910973998670">"允许用户绑定至文字服务(如 SpellCheckerService)的顶级接口。普通应用绝不需要此权限。"</string>
<string name="permlab_bindVpnService" msgid="4708596021161473255">"绑定到 VPN 服务"</string>
- <string name="permdesc_bindVpnService" msgid="2067845564581693905">"允许用户绑定到 VPN 服务的顶级接口。普通应用从不需要此权限。"</string>
+ <string name="permdesc_bindVpnService" msgid="2067845564581693905">"允许用户绑定到 VPN 服务的顶级接口。普通应用绝不需要此权限。"</string>
<string name="permlab_bindWallpaper" msgid="8716400279937856462">"绑定到壁纸"</string>
<string name="permdesc_bindWallpaper" msgid="7108428692595491668">"允许用户绑定到壁纸的顶级接口。普通应用绝不需要此权限。"</string>
<string name="permlab_bindRemoteViews" msgid="5697987759897367099">"绑定到窗口小部件服务"</string>
@@ -460,9 +462,9 @@
<string name="permlab_hardware_test" msgid="4148290860400659146">"测试硬件"</string>
<string name="permdesc_hardware_test" msgid="6597964191208016605">"允许应用控制各种外围设备以进行硬件测试。"</string>
<string name="permlab_callPhone" msgid="3925836347681847954">"直接拨打电话号码"</string>
- <string name="permdesc_callPhone" msgid="6396463004110544744">"允许应用在没有您干预的情况下呼叫电话号码。恶意应用可能会产生意料之外的话费。请注意,此权限不允许应用呼叫紧急电话。"</string>
+ <string name="permdesc_callPhone" msgid="6396463004110544744">"允许应用在没有您干预的情况下拨打电话号码。恶意应用可能会产生您意料之外的话费。请注意,此权限不允许应用拨打紧急呼救电话。"</string>
<string name="permlab_callPrivileged" msgid="4198349211108497879">"直接呼叫任何电话号码"</string>
- <string name="permdesc_callPrivileged" msgid="1689024901509996810">"允许应用在没有您干预的情况下呼叫任何电话号码,包括紧急呼叫号码。恶意应用可能会向紧急服务进行多余以及非法呼叫。"</string>
+ <string name="permdesc_callPrivileged" msgid="1689024901509996810">"允许应用在没有您干预的情况下拨打任何电话号码,包括紧急呼救号码。恶意应用可能会多余以及非法地拨打紧急服务的号码。"</string>
<string name="permlab_performCdmaProvisioning" product="tablet" msgid="4842576994144604821">"直接启动 CDMA 平板电脑设置"</string>
<string name="permlab_performCdmaProvisioning" product="default" msgid="5604848095315421425">"直接启动 CDMA 电话设置"</string>
<string name="permdesc_performCdmaProvisioning" msgid="1994193538802314186">"允许应用启动 CDMA 配置。恶意应用可能会无端启动 CDMA 配置。"</string>
@@ -552,7 +554,7 @@
<string name="permdesc_subscribedFeedsRead" msgid="5557058907906144505">"允许应用获取有关当前同步的 Feed 的详情。"</string>
<string name="permlab_subscribedFeedsWrite" msgid="9015246325408209296">"写入订阅的供稿"</string>
<string name="permdesc_subscribedFeedsWrite" msgid="6928930188826089413">"允许应用修改您当前同步的 Feed。恶意应用可能会更改您的同步 Feed。"</string>
- <string name="permlab_readDictionary" msgid="4107101525746035718">"读取您添加到字典的字词"</string>
+ <string name="permlab_readDictionary" msgid="4107101525746035718">"读取您添加到词典的字词"</string>
<string name="permdesc_readDictionary" msgid="8977815988329283705">"允许应用读取用户可能在用户词典中已存储的任意私有字词、名称和短语。"</string>
<string name="permlab_writeDictionary" msgid="2296383164914812772">"写入用户定义的词典"</string>
<string name="permdesc_writeDictionary" msgid="8185385716255065291">"允许应用向用户词典中写入新词。"</string>
@@ -746,7 +748,7 @@
<string name="lockscreen_transport_pause_description" msgid="7659088786780128001">"“暂停”按钮"</string>
<string name="lockscreen_transport_play_description" msgid="5888422938351019426">"“播放”按钮"</string>
<string name="lockscreen_transport_stop_description" msgid="4562318378766987601">"“停止”按钮"</string>
- <string name="emergency_calls_only" msgid="6733978304386365407">"只能使用紧急呼叫"</string>
+ <string name="emergency_calls_only" msgid="6733978304386365407">"只能使用紧急呼救"</string>
<string name="lockscreen_network_locked_message" msgid="143389224986028501">"网络已锁定"</string>
<string name="lockscreen_sim_puk_locked_message" msgid="7441797339976230">"SIM 卡已用 PUK 码锁定"</string>
<string name="lockscreen_sim_puk_locked_instructions" msgid="8127916255245181063">"请参阅《用户指南》或与客服人员联系。"</string>
@@ -839,7 +841,7 @@
<string name="save_password_message" msgid="767344687139195790">"是否希望浏览器记住此密码?"</string>
<string name="save_password_notnow" msgid="6389675316706699758">"暂不保存"</string>
<string name="save_password_remember" msgid="6491879678996749466">"记住"</string>
- <string name="save_password_never" msgid="8274330296785855105">"从不"</string>
+ <string name="save_password_never" msgid="8274330296785855105">"永不"</string>
<string name="open_permission_deny" msgid="7374036708316629800">"您无权打开此网页。"</string>
<string name="text_copied" msgid="4985729524670131385">"文本已复制到剪贴板。"</string>
<string name="more_item_label" msgid="4650918923083320495">"更多"</string>
@@ -853,6 +855,12 @@
<string name="searchview_description_clear" msgid="1330281990951833033">"清除查询"</string>
<string name="searchview_description_submit" msgid="2688450133297983542">"提交查询"</string>
<string name="searchview_description_voice" msgid="2453203695674994440">"语音搜索"</string>
+ <!-- no translation found for enable_explore_by_touch_warning_title (7460694070309730149) -->
+ <skip />
+ <!-- no translation found for enable_explore_by_touch_warning_message (8655887539089910577) -->
+ <skip />
+ <!-- no translation found for enable_explore_by_touch_warning_message (2708199672852373195) -->
+ <skip />
<string name="oneMonthDurationPast" msgid="7396384508953779925">"1 个月前"</string>
<string name="beforeOneMonthDurationPast" msgid="909134546836499826">"1 个月前"</string>
<plurals name="num_seconds_ago">
@@ -1093,7 +1101,7 @@
<string name="usb_storage_notification_title" msgid="8175892554757216525">"USB 已连接"</string>
<string name="usb_storage_notification_message" msgid="939822783828183763">"触摸可将文件复制到计算机或从计算机复制到存储设备。"</string>
<string name="usb_storage_stop_notification_title" msgid="2336058396663516017">"关闭 USB 存储设备"</string>
- <string name="usb_storage_stop_notification_message" msgid="1656852098555623822">"触摸以关闭 USB 存储设备。"</string>
+ <string name="usb_storage_stop_notification_message" msgid="1656852098555623822">"触摸可关闭 USB 存储设备。"</string>
<string name="usb_storage_stop_title" msgid="660129851708775853">"USB 存储设备正在使用中"</string>
<string name="usb_storage_stop_message" product="nosdcard" msgid="4264025280777219521">"在关闭 USB 存储设备前,请从计算机中卸载(“弹出”)Android 设备的 USB 存储设备。"</string>
<string name="usb_storage_stop_message" product="default" msgid="8043969782460613114">"在关闭 USB 存储设备前,请从计算机中卸载(“弹出”)Android 设备的 SD 卡。"</string>
@@ -1103,7 +1111,7 @@
<string name="dlg_confirm_kill_storage_users_text" msgid="5100428757107469454">"如果您打开 USB 存储设备,您正在使用的某些应用将会停止,并且在您关闭 USB 存储设备前都将无法使用。"</string>
<string name="dlg_error_title" msgid="7323658469626514207">"USB 操作失败"</string>
<string name="dlg_ok" msgid="7376953167039865701">"确定"</string>
- <string name="usb_mtp_notification_title" msgid="3699913097391550394">"作为媒体设备连接"</string>
+ <string name="usb_mtp_notification_title" msgid="3699913097391550394">"已作为媒体设备连接"</string>
<string name="usb_ptp_notification_title" msgid="1960817192216064833">"作为相机连接"</string>
<string name="usb_cd_installer_notification_title" msgid="6774712827892090754">"作为安装程序连接"</string>
<string name="usb_accessory_notification_title" msgid="7848236974087653666">"已连接到 USB 配件"</string>
@@ -1114,11 +1122,15 @@
<string name="extmedia_format_message" product="default" msgid="14131895027543830">"您卡上的所有数据都会丢失。"</string>
<string name="extmedia_format_button_format" msgid="4131064560127478695">"格式化"</string>
<string name="adb_active_notification_title" msgid="6729044778949189918">"已连接 USB 调试"</string>
- <string name="adb_active_notification_message" msgid="1016654627626476142">"触摸以停用 USB 调试。"</string>
+ <string name="adb_active_notification_message" msgid="1016654627626476142">"触摸可停用 USB 调试。"</string>
<string name="select_input_method" msgid="4653387336791222978">"选择输入法"</string>
<string name="configure_input_methods" msgid="9091652157722495116">"设置输入法"</string>
<string name="use_physical_keyboard" msgid="6203112478095117625">"物理键盘"</string>
<string name="hardware" msgid="7517821086888990278">"硬件"</string>
+ <!-- no translation found for select_keyboard_layout_notification_title (1407367017263030773) -->
+ <skip />
+ <!-- no translation found for select_keyboard_layout_notification_message (4465907700449257063) -->
+ <skip />
<string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="candidates_style" msgid="4333913089637062257"><u>"候选"</u></string>
@@ -1166,7 +1178,7 @@
<string name="grant_permissions_header_text" msgid="6874497408201826708">"访问权限请求"</string>
<string name="allow" msgid="7225948811296386551">"允许"</string>
<string name="deny" msgid="2081879885755434506">"拒绝"</string>
- <string name="permission_request_notification_title" msgid="6486759795926237907">"许可权限请求"</string>
+ <string name="permission_request_notification_title" msgid="6486759795926237907">"权限请求"</string>
<string name="permission_request_notification_with_subtitle" msgid="8530393139639560189">"应用对帐户 <xliff:g id="ACCOUNT">%s</xliff:g>"\n" 提出权限请求。"</string>
<string name="input_method_binding_label" msgid="1283557179944992649">"输入法"</string>
<string name="sync_binding_label" msgid="3687969138375092423">"同步"</string>
@@ -1175,7 +1187,7 @@
<string name="chooser_wallpaper" msgid="7873476199295190279">"更改壁纸"</string>
<string name="vpn_title" msgid="19615213552042827">"VPN 已激活"</string>
<string name="vpn_title_long" msgid="6400714798049252294">"“<xliff:g id="APP">%s</xliff:g>”已激活 VPN"</string>
- <string name="vpn_text" msgid="3011306607126450322">"触摸以管理网络。"</string>
+ <string name="vpn_text" msgid="3011306607126450322">"触摸可管理网络。"</string>
<string name="vpn_text_long" msgid="6407351006249174473">"已连接到“<xliff:g id="SESSION">%s</xliff:g>”。触摸可管理网络。"</string>
<string name="upload_file" msgid="2897957172366730416">"选择文件"</string>
<string name="no_file_chosen" msgid="6363648562170759465">"未选定任何文件"</string>
@@ -1184,14 +1196,14 @@
<string name="car_mode_disable_notification_title" msgid="3164768212003864316">"已启用车载模式"</string>
<string name="car_mode_disable_notification_message" msgid="8035230537563503262">"触摸可退出车载模式。"</string>
<string name="tethered_notification_title" msgid="3146694234398202601">"网络共享或热点已启用"</string>
- <string name="tethered_notification_message" msgid="6857031760103062982">"触摸以设置。"</string>
+ <string name="tethered_notification_message" msgid="6857031760103062982">"触摸可进行设置。"</string>
<string name="back_button_label" msgid="2300470004503343439">"上一步"</string>
<string name="next_button_label" msgid="1080555104677992408">"下一步"</string>
<string name="skip_button_label" msgid="1275362299471631819">"跳过"</string>
<string name="throttle_warning_notification_title" msgid="4890894267454867276">"手机流量过多"</string>
- <string name="throttle_warning_notification_message" msgid="3340822228599337743">"触摸以了解有关移动数据使用的详情。"</string>
+ <string name="throttle_warning_notification_message" msgid="3340822228599337743">"触摸可了解有关移动数据使用的详情。"</string>
<string name="throttled_notification_title" msgid="6269541897729781332">"已超出手机数据上限"</string>
- <string name="throttled_notification_message" msgid="5443457321354907181">"触摸以了解有关移动数据使用的详情。"</string>
+ <string name="throttled_notification_message" msgid="5443457321354907181">"触摸可了解有关移动数据使用的详情。"</string>
<string name="no_matches" msgid="8129421908915840737">"无匹配项"</string>
<string name="find_on_page" msgid="1946799233822820384">"在网页上查找"</string>
<plurals name="matches_found">
@@ -1281,14 +1293,14 @@
<string name="data_usage_4g_limit_title" msgid="7636489436819470761">"4G 数据已停用"</string>
<string name="data_usage_mobile_limit_title" msgid="7869402519391631884">"移动数据已停用"</string>
<string name="data_usage_wifi_limit_title" msgid="8992154736441284865">"Wi-Fi 数据网络已停用"</string>
- <string name="data_usage_limit_body" msgid="3317964706973601386">"触摸以启用。"</string>
+ <string name="data_usage_limit_body" msgid="3317964706973601386">"触摸可启用。"</string>
<string name="data_usage_3g_limit_snoozed_title" msgid="7026739121138005231">"已超出 2G-3G 数据流量限制"</string>
<string name="data_usage_4g_limit_snoozed_title" msgid="1106562779311209039">"已超出 4G 数据使用上限"</string>
<string name="data_usage_mobile_limit_snoozed_title" msgid="279240572165412168">"已超出移动数据流量上限"</string>
<string name="data_usage_wifi_limit_snoozed_title" msgid="8743856006384825974">"超出了 Wi-Fi 数据流量上限"</string>
<string name="data_usage_limit_snoozed_body" msgid="7035490278298441767">"超出规定上限 <xliff:g id="SIZE">%s</xliff:g>。"</string>
<string name="data_usage_restricted_title" msgid="5965157361036321914">"后台数据受限制"</string>
- <string name="data_usage_restricted_body" msgid="6741521330997452990">"触摸以删除限制。"</string>
+ <string name="data_usage_restricted_body" msgid="6741521330997452990">"触摸可去除限制。"</string>
<string name="ssl_certificate" msgid="6510040486049237639">"安全证书"</string>
<string name="ssl_certificate_is_valid" msgid="6825263250774569373">"该证书有效。"</string>
<string name="issued_to" msgid="454239480274921032">"颁发给:"</string>
@@ -1312,5 +1324,6 @@
<string name="launchBrowserDefault" msgid="2057951947297614725">"要启动浏览器吗?"</string>
<string name="SetupCallDefault" msgid="5834948469253758575">"要接听电话吗?"</string>
<string name="activity_resolver_use_always" msgid="8017770747801494933">"始终"</string>
- <string name="activity_resolver_use_once" msgid="405646673463328329">"仅此一次"</string>
+ <!-- no translation found for activity_resolver_use_once (2404644797149173758) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml
index 97fcbd6..95b3fa3 100644
--- a/core/res/res/values-zh-rTW/strings.xml
+++ b/core/res/res/values-zh-rTW/strings.xml
@@ -317,6 +317,8 @@
<string name="permdesc_readInputState" msgid="8387754901688728043">"允許應用程式監看您的按鍵操作,包括使用其他應用程式時的按鍵操作,例如輸入密碼 (一般應用程式不需使用)。"</string>
<string name="permlab_bindInputMethod" msgid="3360064620230515776">"連結至輸入法"</string>
<string name="permdesc_bindInputMethod" msgid="3250440322807286331">"允許應用程式繫結至輸入法的頂層介面 (一般應用程式不需使用)。"</string>
+ <string name="permlab_bindAccessibilityService" msgid="5357733942556031593">"繫結至協助工具服務"</string>
+ <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"允許應用程式繫結至協助工具服務的頂層介面 (一般應用程式不需使用)。"</string>
<string name="permlab_bindTextService" msgid="7358378401915287938">"繫結至文字服務"</string>
<string name="permdesc_bindTextService" msgid="8151968910973998670">"允許應用程式繫結至文字服務 (例如 SpellCheckerService) 的頂層介面 (一般應用程式不需使用)。"</string>
<string name="permlab_bindVpnService" msgid="4708596021161473255">"繫結至 VPN 服務"</string>
@@ -853,6 +855,12 @@
<string name="searchview_description_clear" msgid="1330281990951833033">"清除查詢"</string>
<string name="searchview_description_submit" msgid="2688450133297983542">"提交查詢"</string>
<string name="searchview_description_voice" msgid="2453203695674994440">"語音搜尋"</string>
+ <!-- no translation found for enable_explore_by_touch_warning_title (7460694070309730149) -->
+ <skip />
+ <!-- no translation found for enable_explore_by_touch_warning_message (8655887539089910577) -->
+ <skip />
+ <!-- no translation found for enable_explore_by_touch_warning_message (2708199672852373195) -->
+ <skip />
<string name="oneMonthDurationPast" msgid="7396384508953779925">"1 個月以前"</string>
<string name="beforeOneMonthDurationPast" msgid="909134546836499826">"1 個月前"</string>
<plurals name="num_seconds_ago">
@@ -1113,12 +1121,16 @@
<string name="extmedia_format_message" product="nosdcard" msgid="3934016853425761078">"USB 儲存裝置上儲存的所有檔案即將遭到清除。這項動作無法復原!"</string>
<string name="extmedia_format_message" product="default" msgid="14131895027543830">"儲存卡上的所有資料都會消失。"</string>
<string name="extmedia_format_button_format" msgid="4131064560127478695">"格式化"</string>
- <string name="adb_active_notification_title" msgid="6729044778949189918">"USB 偵錯模式已啟用"</string>
+ <string name="adb_active_notification_title" msgid="6729044778949189918">"已連接 USB 偵錯工具"</string>
<string name="adb_active_notification_message" msgid="1016654627626476142">"輕觸即可停用 USB 偵錯。"</string>
<string name="select_input_method" msgid="4653387336791222978">"選擇輸入法"</string>
<string name="configure_input_methods" msgid="9091652157722495116">"設定輸入法"</string>
<string name="use_physical_keyboard" msgid="6203112478095117625">"實體鍵盤"</string>
<string name="hardware" msgid="7517821086888990278">"硬體"</string>
+ <!-- no translation found for select_keyboard_layout_notification_title (1407367017263030773) -->
+ <skip />
+ <!-- no translation found for select_keyboard_layout_notification_message (4465907700449257063) -->
+ <skip />
<string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="candidates_style" msgid="4333913089637062257"><u>"待選項目"</u></string>
@@ -1312,5 +1324,6 @@
<string name="launchBrowserDefault" msgid="2057951947297614725">"啟動「瀏覽器」嗎?"</string>
<string name="SetupCallDefault" msgid="5834948469253758575">"接聽電話嗎?"</string>
<string name="activity_resolver_use_always" msgid="8017770747801494933">"一律採用"</string>
- <string name="activity_resolver_use_once" msgid="405646673463328329">"僅此一次"</string>
+ <!-- no translation found for activity_resolver_use_once (2404644797149173758) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml
index 0c9717f..7966153 100644
--- a/core/res/res/values-zu/strings.xml
+++ b/core/res/res/values-zu/strings.xml
@@ -317,6 +317,8 @@
<string name="permdesc_readInputState" msgid="8387754901688728043">"Ivumela insiza ukuthi ibheke izinkinobho ozicindezelayo ngisho ngabe usebenzisana nezinye izinsiza (njengokubhala amaphasiwedi). Akufanele kudingakele izinsiza ezijwayelekile."</string>
<string name="permlab_bindInputMethod" msgid="3360064620230515776">"hlanganisa indlela yokufakwayo"</string>
<string name="permdesc_bindInputMethod" msgid="3250440322807286331">"Ivumela isimeli ukuhlanganisa uxhumano nomsebenzisi wezinga eliphezulu lendlela yokufaka. Ayisoze yadingeka kwizinhlelo ezivamile."</string>
+ <string name="permlab_bindAccessibilityService" msgid="5357733942556031593">"hlanganisa esevisini yesinqujwana"</string>
+ <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Ivumela isibambi ukuhlanganisa uxhumo nomsebenzisi kwezinga eliphezulu lesevisi yesinqunjwana. Akusoze kwadingekela izinhlelo zokusebenza ezivamile."</string>
<string name="permlab_bindTextService" msgid="7358378401915287938">"bophezela kunsizakalo yombhalo"</string>
<string name="permdesc_bindTextService" msgid="8151968910973998670">"Ivumela umbambi ukuhlanganisa uxhumano nomsebenzisi kwezinga eliphezulu lwesixhumi esibonakalayo sensizakalo yombhalo(isb. InsizakaloYokuhlolaUkubhala). Akusoze kwadingeka kwezinhlelo zokusebenza ezivamile."</string>
<string name="permlab_bindVpnService" msgid="4708596021161473255">"hlanganisa kwinsizakalo ye-VPN"</string>
@@ -853,6 +855,9 @@
<string name="searchview_description_clear" msgid="1330281990951833033">"xazulula umbuzo"</string>
<string name="searchview_description_submit" msgid="2688450133297983542">"Thumela umbuzo"</string>
<string name="searchview_description_voice" msgid="2453203695674994440">"Ukusesha ngezwi"</string>
+ <string name="enable_explore_by_touch_warning_title" msgid="7460694070309730149">"Nika amandla i-Explore by Touch?"</string>
+ <string name="enable_explore_by_touch_warning_message" product="tablet" msgid="8655887539089910577">"I-<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> ifuna ukunika amandla i-Explore by Touch. Uma i-Explore by Touch ikhanya, ungezwa noma ubone izincazelo ezingaphansi komunwe wakho noma wenze izenzo zomzimba ukuze uxhumane nethebhulethi."</string>
+ <string name="enable_explore_by_touch_warning_message" product="default" msgid="2708199672852373195">"I-<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> ifuna ukunika amandla i-Explore by Touch. Uma i-Explore by Touch ikhanya, ungezwa noma ubone izincazelo ezingaphansi komunwe wakho noma wenze izenzo zomzimba ukuze uxhumane nefoni."</string>
<string name="oneMonthDurationPast" msgid="7396384508953779925">"inyanga engu-1 edlule"</string>
<string name="beforeOneMonthDurationPast" msgid="909134546836499826">"Ngaphambi kwenyanga engu-1 edlule"</string>
<plurals name="num_seconds_ago">
@@ -1119,6 +1124,8 @@
<string name="configure_input_methods" msgid="9091652157722495116">"Izilungiselelo zezindlela zokufakwayo"</string>
<string name="use_physical_keyboard" msgid="6203112478095117625">"Ukwakheka kwekhibhodi"</string>
<string name="hardware" msgid="7517821086888990278">"I-Hardware"</string>
+ <string name="select_keyboard_layout_notification_title" msgid="1407367017263030773">"Khetha isendlalelo sekhibhodi"</string>
+ <string name="select_keyboard_layout_notification_message" msgid="4465907700449257063">"Thinta ukuze ukhethe isendlalelo sekhibhodi."</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>"abahlanganyeli"</u></string>
@@ -1312,5 +1319,5 @@
<string name="launchBrowserDefault" msgid="2057951947297614725">"Qala Isiphequluli?"</string>
<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="405646673463328329">"Kanye nje"</string>
+ <string name="activity_resolver_use_once" msgid="2404644797149173758">"Kanje nje"</string>
</resources>
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index 2f540a5..e9a3385 100755
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -2136,7 +2136,8 @@
query the screen. Note: While not recommended, an accessibility service may
decide to ignore this attribute and operate on all views in the view tree. -->
<attr name="importantForAccessibility" format="integer">
- <!-- The system determines whether the view is important for accessibility (recommended). -->
+ <!-- The system determines whether the view is important for accessibility - default
+ (recommended). -->
<enum name="auto" value="0" />
<!-- The view is important for accessibility. -->
<enum name="yes" value="1" />
@@ -2144,6 +2145,40 @@
<enum name="no" value="2" />
</attr>
+ <!-- @hide Controls whether this view can take accessibility focus. -->
+ <attr name="accessibilityFocusable" format="integer">
+ <!-- The system determines whether the view can take accessibility focus - default
+ (recommended).
+ <p>
+ Such a view is consideted by the focus search if it is:
+ <ul>
+ <li>
+ Important for accessibility and actionable (clickable, long clickable, focusable)
+ </li>
+ <li>
+ Important for accessibility, not actionable (clickable, long clickable, focusable),
+ and does not have an actionable predecessor.
+ </li>
+ </ul>
+ An accessibility srvice can request putting accessibility focus on such a view.
+ </p> -->
+ <enum name="auto" value="0" />
+ <!-- The view can take accessibility focus.
+ <p>
+ A view that can take accessibility focus is always considered during focus
+ search and an accessibility service can request putting accessibility focus
+ on it.
+ </p> -->
+ <enum name="yes" value="1" />
+ <!-- The view can not take accessibility focus.
+ <p>
+ A view that can not take accessibility focus is never considered during focus
+ search and an accessibility service can not request putting accessibility focus
+ on it.
+ </p> -->
+ <enum name="no" value="2" />
+ </attr>
+
</declare-styleable>
<!-- Attributes that can be used with a {@link android.view.ViewGroup} or any
diff --git a/core/res/res/values/attrs_manifest.xml b/core/res/res/values/attrs_manifest.xml
index b677513..f24733c 100644
--- a/core/res/res/values/attrs_manifest.xml
+++ b/core/res/res/values/attrs_manifest.xml
@@ -551,13 +551,13 @@
<enum name="sensorLandscape" value="6" />
<!-- Would like to have the screen in portrait orientation, but can
use the sensor to change which direction the screen is facing. -->
- <enum name="sensorPortait" value="7" />
+ <enum name="sensorPortrait" value="7" />
<!-- Would like to have the screen in landscape orientation, turned in
the opposite direction from normal landscape. -->
<enum name="reverseLandscape" value="8" />
<!-- Would like to have the screen in portrait orientation, turned in
the opposite direction from normal portrait. -->
- <enum name="reversePortait" value="9" />
+ <enum name="reversePortrait" value="9" />
<!-- Orientation is determined by a physical orientation sensor:
the display will rotate based on how the user moves the device.
This allows any of the 4 possible rotations, regardless of what
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 98e7769..09e3fbb 100755
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -577,11 +577,11 @@
<!-- True if WallpaperService is enabled -->
<bool name="config_enableWallpaperService">true</bool>
- <!-- Component name of the service providing network location support. -->
- <string name="config_networkLocationProvider" translatable="false">@null</string>
+ <!-- Package name providing network location support. -->
+ <string name="config_networkLocationProviderPackageName" translatable="false">@null</string>
- <!-- Component name of the service providing geocoder API support. -->
- <string name="config_geocodeProvider" translatable="false">@null</string>
+ <!-- Package name providing geocoder API support. -->
+ <string name="config_geocodeProviderPackageName" translatable="false">@null</string>
<!-- Boolean indicating if current platform supports bluetooth SCO for off call
use cases -->
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index a143feb..bf9fe42 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -28,7 +28,6 @@
this.
-->
<java-symbol type="id" name="account_name" />
- <java-symbol type="id" name="account_row_checkmark" />
<java-symbol type="id" name="account_row_icon" />
<java-symbol type="id" name="account_row_text" />
<java-symbol type="id" name="account_type" />
@@ -41,7 +40,6 @@
<java-symbol type="id" name="action_menu_presenter" />
<java-symbol type="id" name="action_mode_close_button" />
<java-symbol type="id" name="activity_chooser_view_content" />
- <java-symbol type="id" name="addAccount" />
<java-symbol type="id" name="albumart" />
<java-symbol type="id" name="alertTitle" />
<java-symbol type="id" name="allow_button" />
@@ -122,7 +120,6 @@
<java-symbol type="id" name="old_app_action" />
<java-symbol type="id" name="old_app_description" />
<java-symbol type="id" name="old_app_icon" />
- <java-symbol type="id" name="overflow_title" />
<java-symbol type="id" name="package_label" />
<java-symbol type="id" name="packages_list" />
<java-symbol type="id" name="pause" />
@@ -212,6 +209,8 @@
<java-symbol type="id" name="inbox_text6" />
<java-symbol type="id" name="inbox_more" />
<java-symbol type="id" name="status_bar_latest_event_content" />
+ <java-symbol type="id" name="action_divider" />
+ <java-symbol type="id" name="overflow_divider" />
<java-symbol type="attr" name="actionModeShareDrawable" />
<java-symbol type="attr" name="alertDialogCenterButtons" />
@@ -301,6 +300,7 @@
<java-symbol type="dimen" name="notification_title_text_size" />
<java-symbol type="dimen" name="notification_subtext_size" />
+ <java-symbol type="string" name="add_account_button_label" />
<java-symbol type="string" name="addToDictionary" />
<java-symbol type="string" name="action_bar_home_description" />
<java-symbol type="string" name="action_bar_up_description" />
@@ -1027,7 +1027,6 @@
<java-symbol type="layout" name="choose_account" />
<java-symbol type="layout" name="choose_account_row" />
<java-symbol type="layout" name="choose_account_type" />
- <java-symbol type="layout" name="choose_selected_account_row" />
<java-symbol type="layout" name="choose_type_and_account" />
<java-symbol type="layout" name="grant_credentials_permission" />
<java-symbol type="layout" name="number_picker" />
@@ -1303,6 +1302,9 @@
<java-symbol type="string" name="global_actions_airplane_mode_off_status" />
<java-symbol type="string" name="global_actions_airplane_mode_on_status" />
<java-symbol type="string" name="global_actions_toggle_airplane_mode" />
+ <java-symbol type="string" name="global_action_silent_mode_off_status" />
+ <java-symbol type="string" name="global_action_silent_mode_on_status" />
+ <java-symbol type="string" name="global_action_toggle_silent_mode" />
<java-symbol type="string" name="invalidPuk" />
<java-symbol type="string" name="keyguard_password_enter_pin_code" />
<java-symbol type="string" name="keyguard_password_enter_puk_code" />
@@ -1457,8 +1459,8 @@
<java-symbol type="string" name="car_mode_disable_notification_title" />
<java-symbol type="string" name="chooser_wallpaper" />
<java-symbol type="string" name="config_datause_iface" />
- <java-symbol type="string" name="config_geocodeProvider" />
- <java-symbol type="string" name="config_networkLocationProvider" />
+ <java-symbol type="string" name="config_geocodeProviderPackageName" />
+ <java-symbol type="string" name="config_networkLocationProviderPackageName" />
<java-symbol type="string" name="config_wimaxManagerClassname" />
<java-symbol type="string" name="config_wimaxNativeLibLocation" />
<java-symbol type="string" name="config_wimaxServiceClassname" />
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 5929439..65457b3 100755
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -3382,9 +3382,8 @@
<string name="choose_account_label">Choose an account</string>
<string name="add_account_label">"Add an account"</string>
- <string name="choose_account_text">"Which account do you want to use?"</string>
- <!-- Button label to add an account [CHAR LIMIT=20] -->
+ <!-- List item to add an account [CHAR LIMIT=20] -->
<string name="add_account_button_label">Add account</string>
<!-- NumberPicker - accessibility support -->
diff --git a/core/res/res/values/styles.xml b/core/res/res/values/styles.xml
index a54cdf1..223d17a 100644
--- a/core/res/res/values/styles.xml
+++ b/core/res/res/values/styles.xml
@@ -239,7 +239,7 @@ please see styles_device_defaults.xml.
</style>
<!-- Notification content styles -->
<style name="TextAppearance.StatusBar.EventContent">
- <item name="android:textColor">#808080</item>
+ <item name="android:textColor">#999999</item>
<item name="android:textSize">@dimen/notification_text_size</item>
</style>
<style name="TextAppearance.StatusBar.EventContent.Title">
@@ -253,11 +253,14 @@ please see styles_device_defaults.xml.
</style>
<style name="TextAppearance.StatusBar.EventContent.Info">
<item name="android:textSize">@dimen/notification_subtext_size</item>
- <item name="android:textColor">#666666</item>
+ <item name="android:textColor">#999999</item>
</style>
<style name="TextAppearance.StatusBar.EventContent.Time">
<item name="android:textSize">@dimen/notification_subtext_size</item>
- <item name="android:textColor">#666666</item>
+ <item name="android:textColor">#999999</item>
+ </style>
+ <style name="TextAppearance.StatusBar.EventContent.Emphasis">
+ <item name="android:textColor">#CCCCCC</item>
</style>
<style name="TextAppearance.Small.CalendarViewWeekDayView">
diff --git a/docs/html/guide/topics/ui/index.jd b/docs/html/guide/topics/ui/index.jd
index 45c9ac9..be07249 100644
--- a/docs/html/guide/topics/ui/index.jd
+++ b/docs/html/guide/topics/ui/index.jd
@@ -148,7 +148,7 @@ this is how you'll listen for events. The View class contains a collection of ne
On<em>&lt;something></em>Listener, each with a callback method called <code>On<em>&lt;something></em>()</code>.
For example, {@link android.view.View.OnClickListener} (for handling "clicks" on a View),
{@link android.view.View.OnTouchListener} (for handling touch screen events in a View), and
-{@link android.view.View.OnKeyListener} (for handling device key presses within a View). So if you want your View
+{@link android.view.View.OnKeyListener} if you want to handle hardware key presses within a View. So if you want your View
to be notified when it is "clicked" (such as when a button is selected), implement OnClickListener and define
its <code>onClick()</code> callback method (where you perform the action upon click), and register it
to the View with <code>{@link android.view.View#setOnClickListener(View.OnClickListener) setOnClickListener()}</code>.
@@ -158,7 +158,7 @@ what you should do when you've implemented your own View class and want to liste
that occur within it. Example events you can handle include when the
screen is touched (<code>{@link android.view.View#onTouchEvent(MotionEvent) onTouchEvent()}</code>), when
the trackball is moved (<code>{@link android.view.View#onTrackballEvent(MotionEvent) onTrackballEvent()}</code>),
-or when a key on the device is pressed (<code>{@link android.view.View#onKeyDown(int, KeyEvent)
+or when a <em>hardware</em> key on the device is pressed (<code>{@link android.view.View#onKeyDown(int, KeyEvent)
onKeyDown()}</code>). This allows you to define the default behavior for each event inside your custom View and determine
whether the event should be passed on to some other child View. Again, these are callbacks to the View class,
so your only chance to define them is when you
diff --git a/docs/html/guide/topics/ui/ui-events.jd b/docs/html/guide/topics/ui/ui-events.jd
index 93bad43..707d4b1 100644
--- a/docs/html/guide/topics/ui/ui-events.jd
+++ b/docs/html/guide/topics/ui/ui-events.jd
@@ -64,7 +64,7 @@ been registered is triggered by user interaction with the item in the UI.</p>
This is called when the user navigates onto or away from the item, using the navigation-keys or trackball.</dd>
<dt><code>onKey()</code></dt>
<dd>From {@link android.view.View.OnKeyListener}.
- This is called when the user is focused on the item and presses or releases a key on the device.</dd>
+ This is called when the user is focused on the item and presses or releases a hardware key on the device.</dd>
<dt><code>onTouch()</code></dt>
<dd>From {@link android.view.View.OnTouchListener}.
This is called when the user performs an action qualified as a touch event, including a press, a release,
@@ -143,13 +143,23 @@ depends on the event. For the few that do, here's why:</p>
within the event, such as a finger gesture, or the eventual up action event.</li>
</ul>
-<p>Remember that key events are always delivered to the View currently in focus. They are dispatched starting from the top
+<p>Remember that hardware key events are always delivered to the View currently in focus. They are dispatched starting from the top
of the View hierarchy, and then down, until they reach the appropriate destination. If your View (or a child of your View)
currently has focus, then you can see the event travel through the <code>{@link android.view.View#dispatchKeyEvent(KeyEvent)
dispatchKeyEvent()}</code> method. As an alternative to capturing key events through your View, you can also receive
all of the events inside your Activity with <code>{@link android.app.Activity#onKeyDown(int,KeyEvent) onKeyDown()}</code>
and <code>{@link android.app.Activity#onKeyUp(int,KeyEvent) onKeyUp()}</code>.</p>
+<p>Also, when thinking about text input for your application, remember that many devices only have software input
+methods. Such methods are not required to be key-based; some may use voice input, handwriting, and so on. Even if
+an input method presents a keyboard-like interface, it will generally <strong>not</strong> trigger the
+<code>{@link android.app.Activity#onKeyDown(int,KeyEvent) onKeyDown()}</code> family of events. You should never
+build a UI that requires specific key presses to be controlled unless you want to limit your application to devices
+with a hardware keyboard. In particular, do not rely on these methods to validate input when the user presses the
+return key; instead, use actions like {@link android.view.inputmethod.EditorInfo#IME_ACTION_DONE} to signal the
+input method how your application expects to react, so it may change its UI in a meaningful way. Avoid assumptions
+about how a software input method should work and just trust it to supply already formatted text to your application.</p>
+
<p class="note"><strong>Note:</strong> Android will call event handlers first and then the appropriate default
handlers from the class definition second. As such, returning <em>true</em> from these event listeners will stop
the propagation of the event to other event listeners and will also block the callback to the
diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java
index 6c7c160..6b9522b 100644
--- a/media/java/android/media/AudioManager.java
+++ b/media/java/android/media/AudioManager.java
@@ -19,6 +19,7 @@ package android.media;
import android.annotation.SdkConstant;
import android.annotation.SdkConstant.SdkConstantType;
import android.app.PendingIntent;
+import android.bluetooth.BluetoothDevice;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
@@ -2376,6 +2377,42 @@ public class AudioManager {
}
}
+ /**
+ * Indicate wired accessory connection state change.
+ * @param device type of device connected/disconnected (AudioManager.DEVICE_OUT_xxx)
+ * @param state new connection state: 1 connected, 0 disconnected
+ * @param name device name
+ * {@hide}
+ */
+ public void setWiredDeviceConnectionState(int device, int state, String name) {
+ IAudioService service = getService();
+ try {
+ service.setWiredDeviceConnectionState(device, state, name);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Dead object in setWiredDeviceConnectionState "+e);
+ }
+ }
+
+ /**
+ * Indicate A2DP sink connection state change.
+ * @param device Bluetooth device connected/disconnected
+ * @param state new connection state (BluetoothProfile.STATE_xxx)
+ * @return a delay in ms that the caller should wait before broadcasting
+ * BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED intent.
+ * {@hide}
+ */
+ public int setBluetoothA2dpDeviceConnectionState(BluetoothDevice device, int state) {
+ IAudioService service = getService();
+ int delay = 0;
+ try {
+ delay = service.setBluetoothA2dpDeviceConnectionState(device, state);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Dead object in setBluetoothA2dpDeviceConnectionState "+e);
+ } finally {
+ return delay;
+ }
+ }
+
/** {@hide} */
public IRingtonePlayer getRingtonePlayer() {
try {
diff --git a/media/java/android/media/AudioService.java b/media/java/android/media/AudioService.java
index 5e338ab..84856bf 100644
--- a/media/java/android/media/AudioService.java
+++ b/media/java/android/media/AudioService.java
@@ -135,6 +135,8 @@ public class AudioService extends IAudioService.Stub implements OnFinished {
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_SET_WIRED_DEVICE_CONNECTION_STATE = 16;
+ private static final int MSG_SET_A2DP_CONNECTION_STATE = 17;
// flags for MSG_PERSIST_VOLUME indicating if current and/or last audible volume should be
@@ -442,15 +444,9 @@ public class AudioService extends IAudioService.Stub implements OnFinished {
// Register for device connection intent broadcasts.
IntentFilter intentFilter =
- new IntentFilter(Intent.ACTION_HEADSET_PLUG);
-
- intentFilter.addAction(BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED);
- intentFilter.addAction(BluetoothHeadset.ACTION_AUDIO_STATE_CHANGED);
+ new IntentFilter(BluetoothHeadset.ACTION_AUDIO_STATE_CHANGED);
intentFilter.addAction(BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED);
intentFilter.addAction(Intent.ACTION_DOCK_EVENT);
- intentFilter.addAction(Intent.ACTION_ANALOG_AUDIO_DOCK_PLUG);
- intentFilter.addAction(Intent.ACTION_DIGITAL_AUDIO_DOCK_PLUG);
- intentFilter.addAction(Intent.ACTION_HDMI_AUDIO_PLUG);
intentFilter.addAction(Intent.ACTION_USB_AUDIO_ACCESSORY_PLUG);
intentFilter.addAction(Intent.ACTION_USB_AUDIO_DEVICE_PLUG);
intentFilter.addAction(Intent.ACTION_BOOT_COMPLETED);
@@ -1961,7 +1957,19 @@ public class AudioService extends IAudioService.Stub implements OnFinished {
deviceList = a2dp.getConnectedDevices();
if (deviceList.size() > 0) {
btDevice = deviceList.get(0);
- handleA2dpConnectionStateChange(btDevice, a2dp.getConnectionState(btDevice));
+ synchronized (mConnectedDevices) {
+ int state = a2dp.getConnectionState(btDevice);
+ int delay = checkSendBecomingNoisyIntent(
+ AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP,
+ (state == BluetoothA2dp.STATE_CONNECTED) ? 1 : 0);
+ sendMsg(mAudioHandler,
+ MSG_SET_A2DP_CONNECTION_STATE,
+ SENDMSG_QUEUE,
+ state,
+ 0,
+ btDevice,
+ delay);
+ }
}
break;
@@ -2262,6 +2270,36 @@ public class AudioService extends IAudioService.Stub implements OnFinished {
return device;
}
+ public void setWiredDeviceConnectionState(int device, int state, String name) {
+ synchronized (mConnectedDevices) {
+ int delay = checkSendBecomingNoisyIntent(device, state);
+ sendMsg(mAudioHandler,
+ MSG_SET_WIRED_DEVICE_CONNECTION_STATE,
+ SENDMSG_QUEUE,
+ device,
+ state,
+ name,
+ delay);
+ }
+ }
+
+ public int setBluetoothA2dpDeviceConnectionState(BluetoothDevice device, int state)
+ {
+ int delay;
+ synchronized (mConnectedDevices) {
+ delay = checkSendBecomingNoisyIntent(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP,
+ (state == BluetoothA2dp.STATE_CONNECTED) ? 1 : 0);
+ sendMsg(mAudioHandler,
+ MSG_SET_A2DP_CONNECTION_STATE,
+ SENDMSG_QUEUE,
+ state,
+ 0,
+ device,
+ delay);
+ }
+ return delay;
+ }
+
///////////////////////////////////////////////////////////////////////////
// Inner classes
///////////////////////////////////////////////////////////////////////////
@@ -2959,6 +2997,14 @@ public class AudioService extends IAudioService.Stub implements OnFinished {
case MSG_BT_HEADSET_CNCT_FAILED:
resetBluetoothSco();
break;
+
+ case MSG_SET_WIRED_DEVICE_CONNECTION_STATE:
+ onSetWiredDeviceConnectionState(msg.arg1, msg.arg2, (String)msg.obj);
+ break;
+
+ case MSG_SET_A2DP_CONNECTION_STATE:
+ onSetA2dpConnectionState((BluetoothDevice)msg.obj, msg.arg1);
+ break;
}
}
}
@@ -3020,7 +3066,6 @@ public class AudioService extends IAudioService.Stub implements OnFinished {
// must be called synchronized on mConnectedDevices
private void makeA2dpDeviceUnavailableNow(String address) {
- sendBecomingNoisyIntent();
AudioSystem.setDeviceConnectionState(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP,
AudioSystem.DEVICE_STATE_UNAVAILABLE,
address);
@@ -3050,7 +3095,7 @@ public class AudioService extends IAudioService.Stub implements OnFinished {
return mAudioHandler.hasMessages(MSG_BTA2DP_DOCK_TIMEOUT);
}
- private void handleA2dpConnectionStateChange(BluetoothDevice btDevice, int state)
+ private void onSetA2dpConnectionState(BluetoothDevice btDevice, int state)
{
if (btDevice == null) {
return;
@@ -3116,6 +3161,76 @@ public class AudioService extends IAudioService.Stub implements OnFinished {
return false;
}
+ // Devices which removal triggers intent ACTION_AUDIO_BECOMING_NOISY. The intent is only
+ // sent if none of these devices is connected.
+ int mBecomingNoisyIntentDevices =
+ AudioSystem.DEVICE_OUT_WIRED_HEADSET | AudioSystem.DEVICE_OUT_WIRED_HEADPHONE |
+ AudioSystem.DEVICE_OUT_ALL_A2DP;
+
+ // must be called before removing the device from mConnectedDevices
+ private int checkSendBecomingNoisyIntent(int device, int state) {
+ int delay = 0;
+ if ((state == 0) && ((device & mBecomingNoisyIntentDevices) != 0)) {
+ int devices = 0;
+ for (int dev : mConnectedDevices.keySet()) {
+ if ((dev & mBecomingNoisyIntentDevices) != 0) {
+ devices |= dev;
+ }
+ }
+ if (devices == device) {
+ delay = 1000;
+ sendBecomingNoisyIntent();
+ }
+ }
+
+ if (mAudioHandler.hasMessages(MSG_SET_A2DP_CONNECTION_STATE) ||
+ mAudioHandler.hasMessages(MSG_SET_WIRED_DEVICE_CONNECTION_STATE)) {
+ delay = 1000;
+ }
+ return delay;
+ }
+
+ private void sendDeviceConnectionIntent(int device, int state, String name)
+ {
+ Intent intent = new Intent();
+
+ intent.putExtra("state", state);
+ intent.putExtra("name", name);
+ intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
+
+ if (device == AudioSystem.DEVICE_OUT_WIRED_HEADSET) {
+ intent.setAction(Intent.ACTION_HEADSET_PLUG);
+ intent.putExtra("microphone", 1);
+ } else if (device == AudioSystem.DEVICE_OUT_WIRED_HEADPHONE) {
+ intent.setAction(Intent.ACTION_HEADSET_PLUG);
+ intent.putExtra("microphone", 0);
+ } else if (device == AudioSystem.DEVICE_OUT_ANLG_DOCK_HEADSET) {
+ intent.setAction(Intent.ACTION_ANALOG_AUDIO_DOCK_PLUG);
+ } else if (device == AudioSystem.DEVICE_OUT_DGTL_DOCK_HEADSET) {
+ intent.setAction(Intent.ACTION_DIGITAL_AUDIO_DOCK_PLUG);
+ } else if (device == AudioSystem.DEVICE_OUT_AUX_DIGITAL) {
+ intent.setAction(Intent.ACTION_HDMI_AUDIO_PLUG);
+ }
+
+ ActivityManagerNative.broadcastStickyIntent(intent, null);
+ }
+
+ private void onSetWiredDeviceConnectionState(int device, int state, String name)
+ {
+ synchronized (mConnectedDevices) {
+ if ((state == 0) && ((device == AudioSystem.DEVICE_OUT_WIRED_HEADSET) ||
+ (device == AudioSystem.DEVICE_OUT_WIRED_HEADPHONE))) {
+ setBluetoothA2dpOnInt(true);
+ }
+ handleDeviceConnection((state == 1), device, "");
+ if ((state != 0) && ((device == AudioSystem.DEVICE_OUT_WIRED_HEADSET) ||
+ (device == AudioSystem.DEVICE_OUT_WIRED_HEADPHONE))) {
+ setBluetoothA2dpOnInt(false);
+ }
+ sendDeviceConnectionIntent(device, state, name);
+ }
+ }
+
/* cache of the address of the last dock the device was connected to */
private String mDockAddress;
@@ -3151,12 +3266,6 @@ public class AudioService extends IAudioService.Stub implements OnFinished {
config = AudioSystem.FORCE_NONE;
}
AudioSystem.setForceUse(AudioSystem.FOR_DOCK, config);
- } else if (action.equals(BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED)) {
- state = intent.getIntExtra(BluetoothProfile.EXTRA_STATE,
- BluetoothProfile.STATE_DISCONNECTED);
- BluetoothDevice btDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
-
- handleA2dpConnectionStateChange(btDevice, state);
} else if (action.equals(BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED)) {
state = intent.getIntExtra(BluetoothProfile.EXTRA_STATE,
BluetoothProfile.STATE_DISCONNECTED);
@@ -3197,43 +3306,9 @@ public class AudioService extends IAudioService.Stub implements OnFinished {
}
}
}
- } else if (action.equals(Intent.ACTION_HEADSET_PLUG)) {
- state = intent.getIntExtra("state", 0);
- int microphone = intent.getIntExtra("microphone", 0);
-
- if (microphone != 0) {
- device = AudioSystem.DEVICE_OUT_WIRED_HEADSET;
- } else {
- device = AudioSystem.DEVICE_OUT_WIRED_HEADPHONE;
- }
- // enable A2DP before notifying headset disconnection to avoid glitches
- if (state == 0) {
- setBluetoothA2dpOnInt(true);
- }
- handleDeviceConnection((state == 1), device, "");
- // disable A2DP after notifying headset connection to avoid glitches
- if (state != 0) {
- setBluetoothA2dpOnInt(false);
- }
- } else if (action.equals(Intent.ACTION_ANALOG_AUDIO_DOCK_PLUG)) {
- state = intent.getIntExtra("state", 0);
- Log.v(TAG, "Broadcast Receiver: Got ACTION_ANALOG_AUDIO_DOCK_PLUG, state = "+state);
- handleDeviceConnection((state == 1), AudioSystem.DEVICE_OUT_ANLG_DOCK_HEADSET, "");
- } else if (action.equals(Intent.ACTION_HDMI_AUDIO_PLUG)) {
- state = intent.getIntExtra("state", 0);
- Log.v(TAG, "Broadcast Receiver: Got ACTION_HDMI_AUDIO_PLUG, state = "+state);
- handleDeviceConnection((state == 1), AudioSystem.DEVICE_OUT_AUX_DIGITAL, "");
- } else if (action.equals(Intent.ACTION_DIGITAL_AUDIO_DOCK_PLUG)) {
- state = intent.getIntExtra("state", 0);
- Log.v(TAG,
- "Broadcast Receiver Got ACTION_DIGITAL_AUDIO_DOCK_PLUG, state = " + state);
- handleDeviceConnection((state == 1), AudioSystem.DEVICE_OUT_DGTL_DOCK_HEADSET, "");
} else if (action.equals(Intent.ACTION_USB_AUDIO_ACCESSORY_PLUG) ||
action.equals(Intent.ACTION_USB_AUDIO_DEVICE_PLUG)) {
state = intent.getIntExtra("state", 0);
- if (state == 0) {
- sendBecomingNoisyIntent();
- }
int alsaCard = intent.getIntExtra("card", -1);
int alsaDevice = intent.getIntExtra("device", -1);
String params = (alsaCard == -1 && alsaDevice == -1 ? ""
diff --git a/media/java/android/media/IAudioService.aidl b/media/java/android/media/IAudioService.aidl
index 7fbe28c..133f30b 100644
--- a/media/java/android/media/IAudioService.aidl
+++ b/media/java/android/media/IAudioService.aidl
@@ -17,6 +17,7 @@
package android.media;
import android.app.PendingIntent;
+import android.bluetooth.BluetoothDevice;
import android.content.ComponentName;
import android.media.IAudioFocusDispatcher;
import android.media.IRemoteControlClient;
@@ -133,4 +134,7 @@ interface IAudioService {
void setRingtonePlayer(IRingtonePlayer player);
IRingtonePlayer getRingtonePlayer();
int getMasterStreamType();
+
+ void setWiredDeviceConnectionState(int device, int state, String name);
+ int setBluetoothA2dpDeviceConnectionState(in BluetoothDevice device, int state);
}
diff --git a/media/java/android/media/MediaPlayer.java b/media/java/android/media/MediaPlayer.java
index 9ed9de0..586f11e 100644
--- a/media/java/android/media/MediaPlayer.java
+++ b/media/java/android/media/MediaPlayer.java
@@ -746,6 +746,7 @@ public class MediaPlayer
try {
request.writeInterfaceToken(IMEDIA_PLAYER);
request.writeInt(INVOKE_ID_SET_VIDEO_SCALE_MODE);
+ request.writeInt(mode);
invoke(request, reply);
} finally {
request.recycle();
diff --git a/media/jni/mediaeditor/VideoEditorMain.cpp b/media/jni/mediaeditor/VideoEditorMain.cpp
index b0c1c35..41ec120 100755
--- a/media/jni/mediaeditor/VideoEditorMain.cpp
+++ b/media/jni/mediaeditor/VideoEditorMain.cpp
@@ -2623,16 +2623,21 @@ videoEditor_init(
M4OSA_Char* tmpString =
(M4OSA_Char *)videoEditJava_getString(&initialized, pEnv, tempPath,
NULL, M4OSA_NULL);
+ M4OSA_UInt32 length = strlen((const char *)tmpString);
+ // Malloc additional 2 bytes for beginning and tail separator.
+ M4OSA_UInt32 pathLength = length + 2;
+
pContext->initParams.pTempPath = (M4OSA_Char *)
- M4OSA_32bitAlignedMalloc(strlen((const char *)tmpString) + 1, 0x0,
- (M4OSA_Char *)"tempPath");
+ M4OSA_32bitAlignedMalloc(pathLength, 0x0, (M4OSA_Char *)"tempPath");
+
//initialize the first char. so that strcat works.
M4OSA_Char *ptmpChar = (M4OSA_Char*)pContext->initParams.pTempPath;
ptmpChar[0] = 0x00;
strncat((char *)pContext->initParams.pTempPath, (const char *)tmpString,
- (size_t)strlen((const char *)tmpString));
+ length);
strncat((char *)pContext->initParams.pTempPath, (const char *)"/", (size_t)1);
free(tmpString);
+ tmpString = NULL;
pContext->mIsUpdateOverlay = false;
pContext->mOverlayFileName = NULL;
pContext->decoders = NULL;
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/stress/MediaRecorderStressTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/stress/MediaRecorderStressTest.java
index 62462bd..6995c60 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/stress/MediaRecorderStressTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/stress/MediaRecorderStressTest.java
@@ -415,59 +415,61 @@ public class MediaRecorderStressTest extends ActivityInstrumentationTestCase2<Me
output.write("Total number of loops: " + NUMBER_OF_TIME_LAPSE_LOOPS + "\n");
try {
- output.write("No of loop: ");
- for (int i = 0; i < NUMBER_OF_TIME_LAPSE_LOOPS; i++) {
- filename = OUTPUT_FILE + i + OUTPUT_FILE_EXT;
- Log.v(TAG, filename);
- runOnLooper(new Runnable() {
- @Override
- public void run() {
- mRecorder = new MediaRecorder();
+ for (int j = 0, n = Camera.getNumberOfCameras(); j < n; j++) {
+ output.write("No of loop: camera " + j);
+ for (int i = 0; i < NUMBER_OF_TIME_LAPSE_LOOPS; i++) {
+ filename = OUTPUT_FILE + j + "_" + i + OUTPUT_FILE_EXT;
+ Log.v(TAG, filename);
+ runOnLooper(new Runnable() {
+ @Override
+ public void run() {
+ mRecorder = new MediaRecorder();
+ }
+ });
+
+ // Set callback
+ mRecorder.setOnErrorListener(mRecorderErrorCallback);
+
+ // Set video source
+ mRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
+
+ // Set camcorder profile for time lapse
+ CamcorderProfile profile =
+ CamcorderProfile.get(j, CamcorderProfile.QUALITY_TIME_LAPSE_HIGH);
+ mRecorder.setProfile(profile);
+
+ // Set the timelapse setting; 0.1 = 10 sec timelapse, 0.5 = 2 sec timelapse, etc.
+ // http://developer.android.com/guide/topics/media/camera.html#time-lapse-video
+ mRecorder.setCaptureRate(captureRate);
+
+ // Set output file
+ mRecorder.setOutputFile(filename);
+
+ // Set the preview display
+ Log.v(TAG, "mediaRecorder setPreviewDisplay");
+ mRecorder.setPreviewDisplay(mSurfaceHolder.getSurface());
+
+ mRecorder.prepare();
+ mRecorder.start();
+ Thread.sleep(record_duration);
+ Log.v(TAG, "Before stop");
+ mRecorder.stop();
+ mRecorder.release();
+
+ // Start the playback
+ MediaPlayer mp = new MediaPlayer();
+ mp.setDataSource(filename);
+ mp.setDisplay(mSurfaceHolder);
+ mp.prepare();
+ mp.start();
+ Thread.sleep(TIME_LAPSE_PLAYBACK_WAIT_TIME);
+ mp.release();
+ validateRecordedVideo(filename);
+ if (remove_video) {
+ removeRecordedVideo(filename);
}
- });
-
- // Set callback
- mRecorder.setOnErrorListener(mRecorderErrorCallback);
-
- // Set video source
- mRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
-
- // Set camcorder profile for time lapse
- CamcorderProfile profile =
- CamcorderProfile.get(CamcorderProfile.QUALITY_TIME_LAPSE_HIGH);
- mRecorder.setProfile(profile);
-
- // Set the timelapse setting; 0.1 = 10 sec timelapse, 0.5 = 2 sec timelapse, etc.
- // http://developer.android.com/guide/topics/media/camera.html#time-lapse-video
- mRecorder.setCaptureRate(captureRate);
-
- // Set output file
- mRecorder.setOutputFile(filename);
-
- // Set the preview display
- Log.v(TAG, "mediaRecorder setPreviewDisplay");
- mRecorder.setPreviewDisplay(mSurfaceHolder.getSurface());
-
- mRecorder.prepare();
- mRecorder.start();
- Thread.sleep(record_duration);
- Log.v(TAG, "Before stop");
- mRecorder.stop();
- mRecorder.release();
-
- // Start the playback
- MediaPlayer mp = new MediaPlayer();
- mp.setDataSource(filename);
- mp.setDisplay(mSurfaceHolder);
- mp.prepare();
- mp.start();
- Thread.sleep(TIME_LAPSE_PLAYBACK_WAIT_TIME);
- mp.release();
- validateRecordedVideo(filename);
- if(remove_video) {
- removeRecordedVideo(filename);
+ output.write(", " + i);
}
- output.write(", " + i);
}
}
catch (IllegalStateException e) {
diff --git a/packages/SystemUI/res/drawable-hdpi/notification_panel_bg.9.png b/packages/SystemUI/res/drawable-hdpi/notification_panel_bg.9.png
index 8a0a30f..ff0bd4c 100644
--- a/packages/SystemUI/res/drawable-hdpi/notification_panel_bg.9.png
+++ b/packages/SystemUI/res/drawable-hdpi/notification_panel_bg.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/notification_panel_bg.9.png b/packages/SystemUI/res/drawable-mdpi/notification_panel_bg.9.png
index 25f15e6..2bbb2c6 100644
--- a/packages/SystemUI/res/drawable-mdpi/notification_panel_bg.9.png
+++ b/packages/SystemUI/res/drawable-mdpi/notification_panel_bg.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/notification_panel_bg.9.png b/packages/SystemUI/res/drawable-sw600dp-hdpi/notification_panel_bg.9.png
index 2ff93d3..e7caeda 100644
--- a/packages/SystemUI/res/drawable-sw600dp-hdpi/notification_panel_bg.9.png
+++ b/packages/SystemUI/res/drawable-sw600dp-hdpi/notification_panel_bg.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/notification_panel_bg.9.png b/packages/SystemUI/res/drawable-sw600dp-mdpi/notification_panel_bg.9.png
index 430f913..ae07083 100644
--- a/packages/SystemUI/res/drawable-sw600dp-mdpi/notification_panel_bg.9.png
+++ b/packages/SystemUI/res/drawable-sw600dp-mdpi/notification_panel_bg.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/notification_panel_bg.9.png b/packages/SystemUI/res/drawable-sw600dp-xhdpi/notification_panel_bg.9.png
index 807241a..8423ef9 100644
--- a/packages/SystemUI/res/drawable-sw600dp-xhdpi/notification_panel_bg.9.png
+++ b/packages/SystemUI/res/drawable-sw600dp-xhdpi/notification_panel_bg.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-hdpi/notification_panel_bg.9.png b/packages/SystemUI/res/drawable-sw720dp-hdpi/notification_panel_bg.9.png
index 2ff93d3..0c20ba2 100644
--- a/packages/SystemUI/res/drawable-sw720dp-hdpi/notification_panel_bg.9.png
+++ b/packages/SystemUI/res/drawable-sw720dp-hdpi/notification_panel_bg.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-mdpi/notification_panel_bg.9.png b/packages/SystemUI/res/drawable-sw720dp-mdpi/notification_panel_bg.9.png
index 430f913..56cd238 100644
--- a/packages/SystemUI/res/drawable-sw720dp-mdpi/notification_panel_bg.9.png
+++ b/packages/SystemUI/res/drawable-sw720dp-mdpi/notification_panel_bg.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-xhdpi/notification_panel_bg.9.png b/packages/SystemUI/res/drawable-sw720dp-xhdpi/notification_panel_bg.9.png
index 807241a..3f05767 100644
--- a/packages/SystemUI/res/drawable-sw720dp-xhdpi/notification_panel_bg.9.png
+++ b/packages/SystemUI/res/drawable-sw720dp-xhdpi/notification_panel_bg.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/notification_panel_bg.9.png b/packages/SystemUI/res/drawable-xhdpi/notification_panel_bg.9.png
index 60e7418..932e0ef 100644
--- a/packages/SystemUI/res/drawable-xhdpi/notification_panel_bg.9.png
+++ b/packages/SystemUI/res/drawable-xhdpi/notification_panel_bg.9.png
Binary files differ
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 4da05d9..74a15f2 100644
--- a/packages/SystemUI/res/layout-sw600dp/status_bar_search_panel.xml
+++ b/packages/SystemUI/res/layout-sw600dp/status_bar_search_panel.xml
@@ -22,53 +22,26 @@
xmlns:prvandroid="http://schemas.android.com/apk/prv/res/android"
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/search_panel_container"
- android:layout_height="wrap_content"
- android:layout_width="match_parent"
- android:paddingBottom="0dip">
-
- <RelativeLayout
- android:id="@+id/search_bg_protect"
- android:layout_width="match_parent"
- android:layout_height="wrap_content">
-
- <RelativeLayout
- android:id="@+id/search_panel_container"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_alignParentBottom="true"
- android:layout_centerHorizontal="true">
-
- <View
- android:layout_width="0dip"
- android:layout_height="0dip"
- android:layout_alignTop="@id/multi_wave_view"
- android:layout_alignLeft="@id/multi_wave_view"
- android:layout_alignRight="@id/multi_wave_view"
- android:layout_alignBottom="@id/multi_wave_view"
- android:layout_marginBottom="@dimen/navigation_bar_size"
- android:background="@drawable/navbar_search_bg_scrim"/>
-
- <com.android.internal.widget.multiwaveview.MultiWaveView
- android:id="@+id/multi_wave_view"
- android:orientation="horizontal"
- android:layout_width="wrap_content"
- android:layout_height="@dimen/navbar_search_panel_height"
- android:layout_alignParentBottom="true"
- android:gravity="top"
-
- prvandroid:targetDrawables="@array/navbar_search_targets"
- prvandroid:targetDescriptions="@array/navbar_search_target_descriptions"
- prvandroid:directionDescriptions="@array/navbar_search_direction_descriptions"
- prvandroid:handleDrawable="@drawable/navbar_search_handle"
- prvandroid:waveDrawable="@drawable/navbar_search_outerring"
- prvandroid:snapMargin="@dimen/navbar_search_snap_margin"
- prvandroid:hitRadius="@dimen/navbar_search_hit_radius"
- prvandroid:feedbackCount="0"
- prvandroid:vibrationDuration="@integer/config_vibration_duration"
- prvandroid:alwaysTrackFinger="true"/>
-
- </RelativeLayout>
-
- </RelativeLayout>
+ android:layout_height="match_parent"
+ android:layout_width="match_parent">
+
+ <com.android.internal.widget.multiwaveview.MultiWaveView
+ android:id="@+id/multi_wave_view"
+ android:layout_width="wrap_content"
+ android:layout_height="@dimen/navbar_search_panel_height"
+ android:layout_gravity="center_horizontal|bottom"
+ android:gravity="center_horizontal|top"
+ android:background="@drawable/navbar_search_bg_scrim"
+
+ prvandroid:targetDrawables="@array/navbar_search_targets"
+ prvandroid:targetDescriptions="@array/navbar_search_target_descriptions"
+ prvandroid:directionDescriptions="@array/navbar_search_direction_descriptions"
+ prvandroid:handleDrawable="@drawable/navbar_search_handle"
+ prvandroid:waveDrawable="@drawable/navbar_search_outerring"
+ prvandroid:snapMargin="@dimen/navbar_search_snap_margin"
+ prvandroid:hitRadius="@dimen/navbar_search_hit_radius"
+ prvandroid:feedbackCount="0"
+ prvandroid:vibrationDuration="@integer/config_vibration_duration"
+ prvandroid:alwaysTrackFinger="true"/>
</com.android.systemui.SearchPanelView>
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 1ae8a69..2a97307 100644
--- a/packages/SystemUI/res/layout-sw720dp/status_bar_search_panel.xml
+++ b/packages/SystemUI/res/layout-sw720dp/status_bar_search_panel.xml
@@ -22,53 +22,27 @@
xmlns:prvandroid="http://schemas.android.com/apk/prv/res/android"
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/search_panel_container"
- android:layout_height="wrap_content"
- android:layout_width="match_parent"
- android:paddingBottom="0dip">
-
- <RelativeLayout
- android:id="@+id/search_bg_protect"
- android:layout_width="match_parent"
- android:layout_height="wrap_content">
-
- <RelativeLayout
- android:id="@+id/search_panel_container"
- android:layout_width="wrap_content"
- android:layout_height="@dimen/navbar_search_panel_height"
- android:layout_alignParentBottom="true"
- android:layout_alignParentLeft="true"
- android:layout_marginLeft="-120dip">
-
- <View
- android:layout_width="0dip"
- android:layout_height="0dip"
- android:layout_alignTop="@id/multi_wave_view"
- android:layout_alignLeft="@id/multi_wave_view"
- android:layout_alignRight="@id/multi_wave_view"
- android:layout_alignBottom="@id/multi_wave_view"
- android:layout_marginBottom="@dimen/navigation_bar_size"
- android:background="@drawable/navbar_search_bg_scrim"/>
-
- <com.android.internal.widget.multiwaveview.MultiWaveView
- android:id="@+id/multi_wave_view"
- android:orientation="horizontal"
- android:layout_width="wrap_content"
- android:layout_height="match_parent"
- android:layout_alignParentBottom="true"
-
- prvandroid:targetDrawables="@array/navbar_search_targets"
- prvandroid:targetDescriptions="@array/navbar_search_target_descriptions"
- prvandroid:directionDescriptions="@array/navbar_search_direction_descriptions"
- prvandroid:handleDrawable="@drawable/navbar_search_handle"
- prvandroid:waveDrawable="@drawable/navbar_search_outerring"
- prvandroid:snapMargin="@dimen/navbar_search_snap_margin"
- prvandroid:hitRadius="@dimen/navbar_search_hit_radius"
- prvandroid:feedbackCount="0"
- prvandroid:vibrationDuration="@integer/config_vibration_duration"
- prvandroid:alwaysTrackFinger="true"/>
-
- </RelativeLayout>
-
- </RelativeLayout>
+ android:layout_height="match_parent"
+ android:layout_width="match_parent">
+
+ <com.android.internal.widget.multiwaveview.MultiWaveView
+ android:id="@+id/multi_wave_view"
+ android:layout_width="wrap_content"
+ android:layout_height="@dimen/navbar_search_panel_height"
+ android:layout_gravity="left|bottom"
+ android:gravity="top|right"
+ android:layout_marginLeft="-150dip"
+ android:background="@drawable/navbar_search_bg_scrim"
+
+ prvandroid:targetDrawables="@array/navbar_search_targets"
+ prvandroid:targetDescriptions="@array/navbar_search_target_descriptions"
+ prvandroid:directionDescriptions="@array/navbar_search_direction_descriptions"
+ prvandroid:handleDrawable="@drawable/navbar_search_handle"
+ prvandroid:waveDrawable="@drawable/navbar_search_outerring"
+ prvandroid:snapMargin="@dimen/navbar_search_snap_margin"
+ prvandroid:hitRadius="@dimen/navbar_search_hit_radius"
+ prvandroid:feedbackCount="0"
+ prvandroid:vibrationDuration="@integer/config_vibration_duration"
+ prvandroid:alwaysTrackFinger="true"/>
</com.android.systemui.SearchPanelView>
diff --git a/packages/SystemUI/res/layout/status_bar_notification_row.xml b/packages/SystemUI/res/layout/status_bar_notification_row.xml
index 7491939..dd70166 100644
--- a/packages/SystemUI/res/layout/status_bar_notification_row.xml
+++ b/packages/SystemUI/res/layout/status_bar_notification_row.xml
@@ -6,6 +6,7 @@
<View
android:id="@+id/top_glow"
android:alpha="0"
+ android:visibility="invisible"
android:layout_width="match_parent"
android:layout_height="@dimen/notification_divider_height"
android:layout_gravity="top|center_horizontal"
@@ -41,6 +42,7 @@
<View
android:id="@+id/bottom_glow"
android:alpha="0"
+ android:visibility="invisible"
android:layout_width="match_parent"
android:layout_height="@dimen/notification_divider_height"
android:layout_gravity="bottom|center_horizontal"
diff --git a/packages/SystemUI/res/values-cs/strings.xml b/packages/SystemUI/res/values-cs/strings.xml
index c41cf6f..2d1f644 100644
--- a/packages/SystemUI/res/values-cs/strings.xml
+++ b/packages/SystemUI/res/values-cs/strings.xml
@@ -47,7 +47,7 @@
<string name="status_bar_settings_auto_brightness_label" msgid="511453614962324674">"AUTOM."</string>
<string name="status_bar_settings_notifications" msgid="397146176280905137">"Oznámení"</string>
<string name="bluetooth_tethered" msgid="7094101612161133267">"Datové připojení Bluetooth se sdílí"</string>
- <string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"Nastavit metody vstupu"</string>
+ <string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"Nastavit metody zadávání"</string>
<string name="status_bar_use_physical_keyboard" msgid="7551903084416057810">"Fyzická klávesnice"</string>
<string name="usb_device_permission_prompt" msgid="834698001271562057">"Povolit aplikaci <xliff:g id="APPLICATION">%1$s</xliff:g> přístup k zařízení USB?"</string>
<string name="usb_accessory_permission_prompt" msgid="5171775411178865750">"Povolit aplikaci <xliff:g id="APPLICATION">%1$s</xliff:g> přístup k perifernímu zařízení USB?"</string>
@@ -77,7 +77,7 @@
<string name="accessibility_home" msgid="8217216074895377641">"Domů"</string>
<string name="accessibility_menu" msgid="316839303324695949">"Menu"</string>
<string name="accessibility_recent" msgid="8571350598987952883">"Nové aplikace"</string>
- <string name="accessibility_ime_switch_button" msgid="5032926134740456424">"Tlačítko přepnutí metody vstupu"</string>
+ <string name="accessibility_ime_switch_button" msgid="5032926134740456424">"Tlačítko přepnutí metody zadávání"</string>
<string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"Tlačítko úpravy velikosti z důvodu kompatibility"</string>
<string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"Zvětšit menší obrázek na větší obrazovku."</string>
<string name="accessibility_bluetooth_connected" msgid="2707027633242983370">"Rozhraní Bluetooth je připojeno."</string>
diff --git a/packages/SystemUI/res/values-de/strings.xml b/packages/SystemUI/res/values-de/strings.xml
index c15a2fa..011d3a3 100644
--- a/packages/SystemUI/res/values-de/strings.xml
+++ b/packages/SystemUI/res/values-de/strings.xml
@@ -47,7 +47,7 @@
<string name="status_bar_settings_auto_brightness_label" msgid="511453614962324674">"AUTO"</string>
<string name="status_bar_settings_notifications" msgid="397146176280905137">"Benachrichtigungen"</string>
<string name="bluetooth_tethered" msgid="7094101612161133267">"Bluetooth-Tethering aktiv"</string>
- <string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"Eingabemethoden einrichten"</string>
+ <string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"Eingabemethoden festlegen"</string>
<string name="status_bar_use_physical_keyboard" msgid="7551903084416057810">"Physische Tastatur"</string>
<string name="usb_device_permission_prompt" msgid="834698001271562057">"App <xliff:g id="APPLICATION">%1$s</xliff:g> Zugriff auf USB-Gerät gewähren?"</string>
<string name="usb_accessory_permission_prompt" msgid="5171775411178865750">"App <xliff:g id="APPLICATION">%1$s</xliff:g> Zugriff auf USB-Zubehör gewähren?"</string>
diff --git a/packages/SystemUI/res/values-en-rGB/strings.xml b/packages/SystemUI/res/values-en-rGB/strings.xml
index 6b40300..f02d09c 100644
--- a/packages/SystemUI/res/values-en-rGB/strings.xml
+++ b/packages/SystemUI/res/values-en-rGB/strings.xml
@@ -41,7 +41,7 @@
<string name="battery_low_why" msgid="7279169609518386372">"Battery use"</string>
<string name="status_bar_settings_settings_button" msgid="3023889916699270224">"Settings"</string>
<string name="status_bar_settings_wifi_button" msgid="1733928151698311923">"Wi-Fi"</string>
- <string name="status_bar_settings_airplane" msgid="4879879698500955300">"Airplane mode"</string>
+ <string name="status_bar_settings_airplane" msgid="4879879698500955300">"Aeroplane mode"</string>
<string name="status_bar_settings_auto_rotation" msgid="3790482541357798421">"Auto-rotate screen"</string>
<string name="status_bar_settings_mute_label" msgid="554682549917429396">"MUTE"</string>
<string name="status_bar_settings_auto_brightness_label" msgid="511453614962324674">"AUTO"</string>
@@ -116,7 +116,7 @@
<string name="accessibility_data_connection_wifi" msgid="2324496756590645221">"Wi-Fi"</string>
<string name="accessibility_no_sim" msgid="8274017118472455155">"No SIM."</string>
<string name="accessibility_bluetooth_tether" msgid="4102784498140271969">"Bluetooth tethering"</string>
- <string name="accessibility_airplane_mode" msgid="834748999790763092">"Airplane mode"</string>
+ <string name="accessibility_airplane_mode" msgid="834748999790763092">"Aeroplane mode"</string>
<string name="accessibility_battery_level" msgid="7451474187113371965">"Battery <xliff:g id="NUMBER">%d</xliff:g> per cent."</string>
<string name="accessibility_settings_button" msgid="799583911231893380">"System settings"</string>
<string name="accessibility_notifications_button" msgid="4498000369779421892">"Notifications."</string>
diff --git a/packages/SystemUI/res/values-es-rUS/strings.xml b/packages/SystemUI/res/values-es-rUS/strings.xml
index 06a9395..be2bf6e 100644
--- a/packages/SystemUI/res/values-es-rUS/strings.xml
+++ b/packages/SystemUI/res/values-es-rUS/strings.xml
@@ -144,7 +144,7 @@
<string name="status_bar_notification_inspect_item_title" msgid="1163547729015390250">"Información de la aplicación"</string>
<string name="notifications_off_title" msgid="8936620513608443224">"Notificaciones desactivadas"</string>
<string name="notifications_off_text" msgid="2529001315769385273">"Toca aquí para volver a activar las notificaciones."</string>
- <string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"La pantalla rotará automáticamente."</string>
+ <string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"La pantalla girará automáticamente."</string>
<string name="accessibility_rotation_lock_on_landscape" msgid="6731197337665366273">"La pantalla está bloqueada en modo horizontal."</string>
<string name="accessibility_rotation_lock_on_portrait" msgid="5809367521644012115">"La pantalla está bloqueada en modo vertical."</string>
</resources>
diff --git a/packages/SystemUI/res/values-es/strings.xml b/packages/SystemUI/res/values-es/strings.xml
index a11194e..aa4e97a 100644
--- a/packages/SystemUI/res/values-es/strings.xml
+++ b/packages/SystemUI/res/values-es/strings.xml
@@ -65,7 +65,7 @@
<string name="screenshot_saving_ticker" msgid="7403652894056693515">"Guardando captura..."</string>
<string name="screenshot_saving_title" msgid="8242282144535555697">"Guardando captura..."</string>
<string name="screenshot_saving_text" msgid="2419718443411738818">"La captura de pantalla se está guardando."</string>
- <string name="screenshot_saved_title" msgid="6461865960961414961">"Captura de pantalla guardada"</string>
+ <string name="screenshot_saved_title" msgid="6461865960961414961">"Captura guardada"</string>
<string name="screenshot_saved_text" msgid="1152839647677558815">"Toca para ver la captura de pantalla"</string>
<string name="screenshot_failed_title" msgid="705781116746922771">"No se ha podido guardar la captura de pantalla."</string>
<string name="screenshot_failed_text" msgid="8134011269572415402">"No se ha podido guardar la captura de pantalla. Puede que el almacenamiento esté en uso."</string>
diff --git a/packages/SystemUI/res/values-sw/strings.xml b/packages/SystemUI/res/values-sw/strings.xml
index 8ce45ed..8f22b81 100644
--- a/packages/SystemUI/res/values-sw/strings.xml
+++ b/packages/SystemUI/res/values-sw/strings.xml
@@ -138,8 +138,8 @@
<string name="accessibility_clear_all" msgid="5235938559247164925">"Futa arifa zote."</string>
<string name="dreams_dock_launcher" msgid="3541196417659166245">"Amilisha hifadhi ya skrini"</string>
<string name="status_bar_notification_inspect_item_title" msgid="1163547729015390250">"Taarifa ya programu"</string>
- <string name="notifications_off_title" msgid="8936620513608443224">"Arifa zimezimwa"</string>
- <string name="notifications_off_text" msgid="2529001315769385273">"Gonga hapa ili kuwasha tena arifa."</string>
+ <string name="notifications_off_title" msgid="8936620513608443224">"Arifa zimelemazwa"</string>
+ <string name="notifications_off_text" msgid="2529001315769385273">"Gonga hapa ili kuwezesha tena arifa."</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Skrini itazunguka kiotomatiki."</string>
<string name="accessibility_rotation_lock_on_landscape" msgid="6731197337665366273">"Skrini imefungwa sasa katika uelekezo wa mandhari."</string>
<string name="accessibility_rotation_lock_on_portrait" msgid="5809367521644012115">"Skrini imefungwa katika uelekeo wa picha."</string>
diff --git a/packages/SystemUI/res/values-vi/strings.xml b/packages/SystemUI/res/values-vi/strings.xml
index 02d0138..eef2c83 100644
--- a/packages/SystemUI/res/values-vi/strings.xml
+++ b/packages/SystemUI/res/values-vi/strings.xml
@@ -142,7 +142,7 @@
<string name="status_bar_notification_inspect_item_title" msgid="1163547729015390250">"Thông tin về ứng dụng"</string>
<string name="notifications_off_title" msgid="8936620513608443224">"Tắt thông báo"</string>
<string name="notifications_off_text" msgid="2529001315769385273">"Chạm vào đây để bật lại thông báo."</string>
- <string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Màn hinh sẽ xoay tự động."</string>
+ <string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Màn hình sẽ xoay tự động."</string>
<string name="accessibility_rotation_lock_on_landscape" msgid="6731197337665366273">"Màn hình hiện bị khóa theo hướng ngang."</string>
<string name="accessibility_rotation_lock_on_portrait" msgid="5809367521644012115">"Màn hình hiện bị khóa theo hướng dọc."</string>
</resources>
diff --git a/packages/SystemUI/res/values-zh-rCN/strings.xml b/packages/SystemUI/res/values-zh-rCN/strings.xml
index 007ee96..ca29738 100644
--- a/packages/SystemUI/res/values-zh-rCN/strings.xml
+++ b/packages/SystemUI/res/values-zh-rCN/strings.xml
@@ -72,7 +72,7 @@
<string name="usb_preference_title" msgid="6551050377388882787">"USB 文件传输选项"</string>
<string name="use_mtp_button_title" msgid="4333504413563023626">"作为媒体播放器 (MTP) 装载"</string>
<string name="use_ptp_button_title" msgid="7517127540301625751">"作为摄像头 (PTP) 装载"</string>
- <string name="installer_cd_button_title" msgid="2312667578562201583">"安装适用于苹果机的“Android 文件传输”应用"</string>
+ <string name="installer_cd_button_title" msgid="2312667578562201583">"安装适用于 Mac 的 Android 文件传输应用"</string>
<string name="accessibility_back" msgid="567011538994429120">"返回"</string>
<string name="accessibility_home" msgid="8217216074895377641">"主屏幕"</string>
<string name="accessibility_menu" msgid="316839303324695949">"菜单"</string>
@@ -145,6 +145,6 @@
<string name="notifications_off_title" msgid="8936620513608443224">"通知功能已停用"</string>
<string name="notifications_off_text" msgid="2529001315769385273">"点按此处可重新启用通知功能。"</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"屏幕会自动旋转。"</string>
- <string name="accessibility_rotation_lock_on_landscape" msgid="6731197337665366273">"屏幕锁定为横向浏览模式。"</string>
- <string name="accessibility_rotation_lock_on_portrait" msgid="5809367521644012115">"屏幕已锁定为纵向浏览模式。"</string>
+ <string name="accessibility_rotation_lock_on_landscape" msgid="6731197337665366273">"屏幕锁定为横向模式。"</string>
+ <string name="accessibility_rotation_lock_on_portrait" msgid="5809367521644012115">"屏幕锁定为纵向模式。"</string>
</resources>
diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml
index 2786013..26dba67 100644
--- a/packages/SystemUI/res/values/config.xml
+++ b/packages/SystemUI/res/values/config.xml
@@ -57,7 +57,13 @@
<!-- Show rotation lock button in phone-style notification panel. -->
<bool name="config_showRotationLock">true</bool>
+ <!-- Amount of time to hold off before showing the search panel when the user presses home -->
+ <integer name="config_show_search_delay">200</integer>
+
+ <!-- Vibration duration for MultiWaveView used in SearchPanelView -->
+ <integer translatable="false" name="config_vibration_duration">0</integer>
+
<!-- Vibration duration for MultiWaveView used in SearchPanelView -->
- <integer translatable="false" name="config_vibration_duration">20</integer>
+ <integer translatable="false" name="config_search_panel_view_vibration_duration">20</integer>
</resources>
diff --git a/packages/SystemUI/src/com/android/systemui/DreamsDockLauncher.java b/packages/SystemUI/src/com/android/systemui/DreamsDockLauncher.java
index 1db2a7f..73249b4 100644
--- a/packages/SystemUI/src/com/android/systemui/DreamsDockLauncher.java
+++ b/packages/SystemUI/src/com/android/systemui/DreamsDockLauncher.java
@@ -58,8 +58,8 @@ public class DreamsDockLauncher extends Activity {
@Override
public void onReceive(Context context, Intent intent) {
final boolean activateOnDock = 0 != Settings.Secure.getInt(
- context.getContentResolver(),
- Settings.Secure.SCREENSAVER_ACTIVATE_ON_DOCK, 1);
+ context.getContentResolver(),
+ Settings.Secure.SCREENSAVER_ACTIVATE_ON_DOCK, 0);
if (!activateOnDock) return;
diff --git a/packages/SystemUI/src/com/android/systemui/ExpandHelper.java b/packages/SystemUI/src/com/android/systemui/ExpandHelper.java
index ba3336b..df41d25 100644
--- a/packages/SystemUI/src/com/android/systemui/ExpandHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/ExpandHelper.java
@@ -17,17 +17,17 @@
package com.android.systemui;
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.content.Context;
-import android.graphics.RectF;
import android.util.Log;
import android.view.MotionEvent;
import android.view.ScaleGestureDetector;
import android.view.View;
import android.view.ViewGroup;
import android.view.View.OnClickListener;
-import com.android.internal.widget.SizeAdaptiveLayout;
public class ExpandHelper implements Gefingerpoken, OnClickListener {
public interface Callback {
@@ -130,8 +130,28 @@ public class ExpandHelper implements Gefingerpoken, OnClickListener {
mScaleAnimation = ObjectAnimator.ofFloat(mScaler, "height", 0f);
mScaleAnimation.setDuration(EXPAND_DURATION);
+ AnimatorListenerAdapter glowVisibilityController = new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationStart(Animator animation) {
+ View target = (View) ((ObjectAnimator) animation).getTarget();
+ if (target.getAlpha() <= 0.0f) {
+ target.setVisibility(View.VISIBLE);
+ }
+ }
+
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ View target = (View) ((ObjectAnimator) animation).getTarget();
+ if (target.getAlpha() <= 0.0f) {
+ target.setVisibility(View.INVISIBLE);
+ }
+ }
+ };
+
mGlowTopAnimation = ObjectAnimator.ofFloat(null, "alpha", 0f);
+ mGlowTopAnimation.addListener(glowVisibilityController);
mGlowBottomAnimation = ObjectAnimator.ofFloat(null, "alpha", 0f);
+ mGlowBottomAnimation.addListener(glowVisibilityController);
mGlowAnimationSet = new AnimatorSet();
mGlowAnimationSet.play(mGlowTopAnimation).with(mGlowBottomAnimation);
mGlowAnimationSet.setDuration(GLOW_DURATION);
@@ -225,10 +245,19 @@ public class ExpandHelper implements Gefingerpoken, OnClickListener {
// set it explicitly in reponse to touches.
mCurrViewTopGlow.setAlpha(glow);
mCurrViewBottomGlow.setAlpha(glow);
+ handleGlowVisibility();
}
}
}
}
+
+ private void handleGlowVisibility() {
+ mCurrViewTopGlow.setVisibility(mCurrViewTopGlow.getAlpha() <= 0.0f ?
+ View.INVISIBLE : View.VISIBLE);
+ mCurrViewBottomGlow.setVisibility(mCurrViewBottomGlow.getAlpha() <= 0.0f ?
+ View.INVISIBLE : View.VISIBLE);
+ }
+
public boolean onInterceptTouchEvent(MotionEvent ev) {
if (DEBUG) Log.d(TAG, "interceptTouch: act=" + (ev.getAction()) +
" stretching=" + mStretching);
diff --git a/packages/SystemUI/src/com/android/systemui/SearchPanelView.java b/packages/SystemUI/src/com/android/systemui/SearchPanelView.java
index 90f94fc..af88a06 100644
--- a/packages/SystemUI/src/com/android/systemui/SearchPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/SearchPanelView.java
@@ -16,9 +16,7 @@
package com.android.systemui;
-import android.animation.Animator;
import android.animation.LayoutTransition;
-import android.app.ActivityManagerNative;
import android.app.ActivityOptions;
import android.app.SearchManager;
import android.content.ActivityNotFoundException;
@@ -26,8 +24,10 @@ import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
+import android.content.res.Resources;
+import android.os.Vibrator;
+import android.provider.Settings;
import android.util.AttributeSet;
-import android.util.Log;
import android.util.Slog;
import android.view.MotionEvent;
import android.view.View;
@@ -35,22 +35,22 @@ import android.view.ViewGroup;
import android.view.ViewTreeObserver;
import android.view.ViewTreeObserver.OnPreDrawListener;
import android.widget.FrameLayout;
-
import com.android.internal.widget.multiwaveview.MultiWaveView;
import com.android.internal.widget.multiwaveview.MultiWaveView.OnTriggerListener;
-import com.android.server.am.ActivityManagerService;
import com.android.systemui.R;
import com.android.systemui.recent.StatusBarTouchProxy;
import com.android.systemui.statusbar.BaseStatusBar;
+import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.phone.PhoneStatusBar;
import com.android.systemui.statusbar.tablet.StatusBarPanel;
import com.android.systemui.statusbar.tablet.TabletStatusBar;
public class SearchPanelView extends FrameLayout implements
- StatusBarPanel, Animator.AnimatorListener {
+ StatusBarPanel {
+ private static final int SEARCH_PANEL_HOLD_DURATION = 500;
static final String TAG = "SearchPanelView";
static final boolean DEBUG = TabletStatusBar.DEBUG || PhoneStatusBar.DEBUG || false;
- private Context mContext;
+ private final Context mContext;
private BaseStatusBar mBar;
private StatusBarTouchProxy mStatusBarTouchProxy;
@@ -78,7 +78,7 @@ public class SearchPanelView extends FrameLayout implements
Intent intent = getAssistIntent();
return intent == null ? false
: mContext.getPackageManager().queryIntentActivities(intent,
- PackageManager.MATCH_DEFAULT_ONLY).size() > 0;
+ PackageManager.MATCH_DEFAULT_ONLY).size() > 0;
}
private Intent getAssistIntent() {
@@ -106,7 +106,11 @@ public class SearchPanelView extends FrameLayout implements
}
private void startAssistActivity() {
+ // Close Recent Apps if needed
+ mBar.animateCollapse(CommandQueue.FLAG_EXCLUDE_SEARCH_PANEL);
+ // Launch Assist
Intent intent = getAssistIntent();
+ if (intent == null) return;
try {
ActivityOptions opts = ActivityOptions.makeCustomAnimation(mContext,
R.anim.search_launch_enter, R.anim.search_launch_exit);
@@ -120,7 +124,7 @@ public class SearchPanelView extends FrameLayout implements
final MultiWaveView.OnTriggerListener mMultiWaveViewListener
= new MultiWaveView.OnTriggerListener() {
- private int mTarget = -1;
+ private boolean mWaitingForLaunch;
public void onGrabbed(View v, int handle) {
}
@@ -129,26 +133,29 @@ public class SearchPanelView extends FrameLayout implements
}
public void onGrabbedStateChange(View v, int handle) {
- if (mTarget == -1 && OnTriggerListener.NO_HANDLE == handle) {
+ if (!mWaitingForLaunch && OnTriggerListener.NO_HANDLE == handle) {
mBar.hideSearchPanel();
}
}
- public void onTrigger(View v, int target) {
- mTarget = target;
+ public void onTrigger(View v, final int target) {
+ final int resId = mMultiWaveView.getResourceIdForTarget(target);
+ switch (resId) {
+ case com.android.internal.R.drawable.ic_lockscreen_search:
+ mWaitingForLaunch = true;
+ startAssistActivity();
+ vibrate();
+ postDelayed(new Runnable() {
+ public void run() {
+ mWaitingForLaunch = false;
+ mBar.hideSearchPanel();
+ }
+ }, SEARCH_PANEL_HOLD_DURATION);
+ break;
+ }
}
public void onFinishFinalAnimation() {
- if (mTarget != -1) {
- final int resId = mMultiWaveView.getResourceIdForTarget(mTarget);
- mTarget = -1; // a safety to make sure we never launch w/o prior call to onTrigger
- switch (resId) {
- case com.android.internal.R.drawable.ic_lockscreen_search:
- startAssistActivity();
- break;
- }
- mBar.hideSearchPanel();
- }
}
};
@@ -156,7 +163,7 @@ public class SearchPanelView extends FrameLayout implements
protected void onFinishInflate() {
super.onFinishInflate();
mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
- mSearchTargetsContainer = (ViewGroup) findViewById(R.id.search_panel_container);
+ mSearchTargetsContainer = findViewById(R.id.search_panel_container);
mStatusBarTouchProxy = (StatusBarTouchProxy) findViewById(R.id.status_bar_touch_proxy);
// TODO: fetch views
mMultiWaveView = (MultiWaveView) findViewById(R.id.multi_wave_view);
@@ -182,7 +189,7 @@ public class SearchPanelView extends FrameLayout implements
}
}
- private OnPreDrawListener mPreDrawListener = new ViewTreeObserver.OnPreDrawListener() {
+ private final OnPreDrawListener mPreDrawListener = new ViewTreeObserver.OnPreDrawListener() {
public boolean onPreDraw() {
getViewTreeObserver().removeOnPreDrawListener(this);
mMultiWaveView.resumeAnimations();
@@ -190,16 +197,22 @@ public class SearchPanelView extends FrameLayout implements
}
};
+ private void vibrate() {
+ Context context = getContext();
+ if (Settings.System.getInt(context.getContentResolver(),
+ Settings.System.HAPTIC_FEEDBACK_ENABLED, 1) != 0) {
+ Resources res = context.getResources();
+ Vibrator vibrator = (Vibrator) context.getSystemService(Context.VIBRATOR_SERVICE);
+ vibrator.vibrate(res.getInteger(R.integer.config_search_panel_view_vibration_duration));
+ }
+ }
+
public void show(final boolean show, boolean animate) {
- if (animate) {
- if (mShowing != show) {
- mShowing = show;
- // TODO: start animating ring
- }
- } else {
- mShowing = show;
- onAnimationEnd(null);
+ if (!show) {
+ final LayoutTransition transitioner = animate ? createLayoutTransitioner() : null;
+ ((ViewGroup) mSearchTargetsContainer).setLayoutTransition(transitioner);
}
+ mShowing = show;
if (show) {
if (getVisibility() != View.VISIBLE) {
setVisibility(View.VISIBLE);
@@ -207,6 +220,7 @@ public class SearchPanelView extends FrameLayout implements
// right before we are drawn
mMultiWaveView.suspendAnimations();
getViewTreeObserver().addOnPreDrawListener(mPreDrawListener);
+ vibrate();
}
setFocusable(true);
setFocusableInTouchMode(true);
@@ -219,31 +233,12 @@ public class SearchPanelView extends FrameLayout implements
public void hide(boolean animate) {
if (mBar != null) {
// This will indirectly cause show(false, ...) to get called
- mBar.animateCollapse();
+ mBar.animateCollapse(CommandQueue.FLAG_EXCLUDE_NONE);
} else {
setVisibility(View.INVISIBLE);
}
}
- public void onAnimationCancel(Animator animation) {
- }
-
- public void onAnimationEnd(Animator animation) {
- if (mShowing) {
- final LayoutTransition transitioner = new LayoutTransition();
- ((ViewGroup)mSearchTargetsContainer).setLayoutTransition(transitioner);
- createCustomAnimations(transitioner);
- } else {
- ((ViewGroup)mSearchTargetsContainer).setLayoutTransition(null);
- }
- }
-
- public void onAnimationRepeat(Animator animation) {
- }
-
- public void onAnimationStart(Animator animation) {
- }
-
/**
* We need to be aligned at the bottom. LinearLayout can't do this, so instead,
* let LinearLayout do all the hard work, and then shift everything down to the bottom.
@@ -290,9 +285,11 @@ public class SearchPanelView extends FrameLayout implements
}
}
- private void createCustomAnimations(LayoutTransition transitioner) {
+ private LayoutTransition createLayoutTransitioner() {
+ LayoutTransition transitioner = new LayoutTransition();
transitioner.setDuration(200);
transitioner.setStartDelay(LayoutTransition.CHANGE_DISAPPEARING, 0);
transitioner.setAnimator(LayoutTransition.DISAPPEARING, null);
+ return transitioner;
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/recent/RecentsHorizontalScrollView.java b/packages/SystemUI/src/com/android/systemui/recent/RecentsHorizontalScrollView.java
index 9f801b0..1302c1f 100644
--- a/packages/SystemUI/src/com/android/systemui/recent/RecentsHorizontalScrollView.java
+++ b/packages/SystemUI/src/com/android/systemui/recent/RecentsHorizontalScrollView.java
@@ -83,6 +83,12 @@ public class RecentsHorizontalScrollView extends HorizontalScrollView
setLayoutTransition(null);
mLinearLayout.removeAllViews();
+ for (int i = 0; i < mRecycledViews.size(); i++) {
+ View child = mRecycledViews.get(i);
+ if (child.getParent() != null) {
+ throw new RuntimeException("Recycled child has a parent");
+ }
+ }
for (int i = 0; i < mAdapter.getCount(); i++) {
View old = null;
if (mRecycledViews.size() != 0) {
@@ -183,6 +189,9 @@ public class RecentsHorizontalScrollView extends HorizontalScrollView
public void onChildDismissed(View v) {
mRecycledViews.add(v);
mLinearLayout.removeView(v);
+ if (v.getParent() != null) {
+ throw new RuntimeException("Recycled child has parent");
+ }
mCallback.handleSwipe(v);
// Restore the alpha/translation parameters to what they were before swiping
// (for when these items are recycled)
@@ -354,9 +363,15 @@ public class RecentsHorizontalScrollView extends HorizontalScrollView
mNumItemsInOneScreenful =
(int) FloatMath.ceil(dm.widthPixels / (float) child.getMeasuredWidth());
mRecycledViews.add(child);
+ if (child.getParent() != null) {
+ throw new RuntimeException("First recycled child has parent");
+ }
for (int i = 0; i < mNumItemsInOneScreenful - 1; i++) {
mRecycledViews.add(mAdapter.createView(mLinearLayout));
+ if (mRecycledViews.get(mRecycledViews.size() - 1).getParent() != null) {
+ throw new RuntimeException("Recycled child has parent");
+ }
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java b/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java
index 39d686f..587bfe8 100644
--- a/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java
@@ -58,6 +58,7 @@ import android.widget.TextView;
import com.android.systemui.R;
import com.android.systemui.statusbar.BaseStatusBar;
+import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.phone.PhoneStatusBar;
import com.android.systemui.statusbar.tablet.StatusBarPanel;
import com.android.systemui.statusbar.tablet.TabletStatusBar;
@@ -308,7 +309,7 @@ public class RecentsPanelView extends FrameLayout implements OnItemClickListener
// if there are no apps, either bring up a "No recent apps" message, or just
// quit early
- boolean noApps = (mRecentTaskDescriptions.size() == 0);
+ boolean noApps = !mFirstScreenful && (mRecentTaskDescriptions.size() == 0);
if (mRecentsNoApps != null) {
mRecentsNoApps.setVisibility(noApps ? View.VISIBLE : View.INVISIBLE);
} else {
@@ -368,7 +369,7 @@ public class RecentsPanelView extends FrameLayout implements OnItemClickListener
}
if (mBar != null) {
// This will indirectly cause show(false, ...) to get called
- mBar.animateCollapse();
+ mBar.animateCollapse(CommandQueue.FLAG_EXCLUDE_NONE);
}
}
@@ -822,7 +823,7 @@ public class RecentsPanelView extends FrameLayout implements OnItemClickListener
if (viewHolder != null) {
final TaskDescription ad = viewHolder.taskDescription;
startApplicationDetailsActivity(ad.packageName);
- mBar.animateCollapse();
+ mBar.animateCollapse(CommandQueue.FLAG_EXCLUDE_NONE);
} else {
throw new IllegalStateException("Oops, no tag on view " + selectedView);
}
diff --git a/packages/SystemUI/src/com/android/systemui/recent/RecentsVerticalScrollView.java b/packages/SystemUI/src/com/android/systemui/recent/RecentsVerticalScrollView.java
index c1597e0..f682203 100644
--- a/packages/SystemUI/src/com/android/systemui/recent/RecentsVerticalScrollView.java
+++ b/packages/SystemUI/src/com/android/systemui/recent/RecentsVerticalScrollView.java
@@ -84,6 +84,12 @@ public class RecentsVerticalScrollView extends ScrollView
setLayoutTransition(null);
mLinearLayout.removeAllViews();
+ for (int i = 0; i < mRecycledViews.size(); i++) {
+ View child = mRecycledViews.get(i);
+ if (child.getParent() != null) {
+ throw new RuntimeException("Recycled child has parent");
+ }
+ }
// Once we can clear the data associated with individual item views,
// we can get rid of the removeAllViews() and the code below will
// recycle them.
@@ -95,6 +101,9 @@ public class RecentsVerticalScrollView extends ScrollView
}
final View view = mAdapter.getView(i, old, mLinearLayout);
+ if (view.getParent() != null) {
+ throw new RuntimeException("Recycled child has parent");
+ }
if (mPerformanceHelper != null) {
mPerformanceHelper.addViewCallback(view);
@@ -133,6 +142,9 @@ public class RecentsVerticalScrollView extends ScrollView
thumbnailView.setClickable(true);
thumbnailView.setOnClickListener(launchAppListener);
thumbnailView.setOnLongClickListener(longClickListener);
+ if (view.getParent() != null) {
+ throw new RuntimeException("Recycled child has parent");
+ }
// We don't want to dismiss recents if a user clicks on the app title
// (we also don't want to launch the app either, though, because the
@@ -142,6 +154,9 @@ public class RecentsVerticalScrollView extends ScrollView
appTitle.setOnTouchListener(noOpListener);
final View calloutLine = view.findViewById(R.id.recents_callout_line);
calloutLine.setOnTouchListener(noOpListener);
+ if (view.getParent() != null) {
+ throw new RuntimeException("Recycled child has parent");
+ }
mLinearLayout.addView(view);
}
@@ -190,6 +205,9 @@ public class RecentsVerticalScrollView extends ScrollView
public void onChildDismissed(View v) {
mRecycledViews.add(v);
mLinearLayout.removeView(v);
+ if (v.getParent() != null) {
+ throw new RuntimeException("Recycled child has parent");
+ }
mCallback.handleSwipe(v);
// Restore the alpha/translation parameters to what they were before swiping
// (for when these items are recycled)
@@ -363,9 +381,15 @@ public class RecentsVerticalScrollView extends ScrollView
mNumItemsInOneScreenful =
(int) FloatMath.ceil(dm.heightPixels / (float) child.getMeasuredHeight());
mRecycledViews.add(child);
+ if (child.getParent() != null) {
+ throw new RuntimeException("First recycled child has parent");
+ }
for (int i = 0; i < mNumItemsInOneScreenful - 1; i++) {
mRecycledViews.add(mAdapter.createView(mLinearLayout));
+ if (mRecycledViews.get(mRecycledViews.size() - 1).getParent() != null) {
+ throw new RuntimeException("Recycled child has parent");
+ }
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
index a352748..f088e0e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
@@ -253,7 +253,7 @@ public abstract class BaseStatusBar extends SystemUI implements
mContext.startActivity(intent);
}
- protected View.OnLongClickListener getNotificationLongClicker() {
+ protected View.OnLongClickListener getNotificationLongClicker() {
return new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
@@ -268,7 +268,7 @@ public abstract class BaseStatusBar extends SystemUI implements
public boolean onMenuItemClick(MenuItem item) {
if (item.getItemId() == R.id.notification_inspect_item) {
startApplicationDetailsActivity(packageNameF);
- animateCollapse();
+ animateCollapse(CommandQueue.FLAG_EXCLUDE_NONE);
} else {
return false;
}
@@ -618,7 +618,7 @@ public abstract class BaseStatusBar extends SystemUI implements
}
// close the shade if it was open
- animateCollapse();
+ animateCollapse(CommandQueue.FLAG_EXCLUDE_NONE);
visibilityChanged(false);
// If this click was on the intruder alert, hide that instead
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java b/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java
index 4209354..a00d95a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java
@@ -66,6 +66,13 @@ public class CommandQueue extends IStatusBar.Stub {
private static final int MSG_SET_NAVIGATION_ICON_HINTS = 14 << MSG_SHIFT;
+ public static final int FLAG_EXCLUDE_NONE = 0;
+ public static final int FLAG_EXCLUDE_SEARCH_PANEL = 1 << 0;
+ public static final int FLAG_EXCLUDE_RECENTS_PANEL = 1 << 1;
+ public static final int FLAG_EXCLUDE_NOTIFICATION_PANEL = 1 << 2;
+ public static final int FLAG_EXCLUDE_INPUT_METHODS_PANEL = 1 << 3;
+ public static final int FLAG_EXCLUDE_COMPAT_MODE_PANEL = 1 << 4;
+
private StatusBarIconList mList;
private Callbacks mCallbacks;
private Handler mHandler = new H();
@@ -88,7 +95,7 @@ public class CommandQueue extends IStatusBar.Stub {
public void removeNotification(IBinder key);
public void disable(int state);
public void animateExpand();
- public void animateCollapse();
+ public void animateCollapse(int flags);
public void setSystemUiVisibility(int vis, int mask);
public void topAppWindowChanged(boolean visible);
public void setImeWindowStatus(IBinder token, int vis, int backDisposition);
@@ -161,9 +168,13 @@ public class CommandQueue extends IStatusBar.Stub {
}
public void animateCollapse() {
+ animateCollapse(CommandQueue.FLAG_EXCLUDE_NONE);
+ }
+
+ public void animateCollapse(int flags) {
synchronized (mList) {
mHandler.removeMessages(MSG_SET_VISIBILITY);
- mHandler.obtainMessage(MSG_SET_VISIBILITY, OP_COLLAPSE, 0, null).sendToTarget();
+ mHandler.obtainMessage(MSG_SET_VISIBILITY, OP_COLLAPSE, flags, null).sendToTarget();
}
}
@@ -277,7 +288,7 @@ public class CommandQueue extends IStatusBar.Stub {
if (msg.arg1 == OP_EXPAND) {
mCallbacks.animateExpand();
} else {
- mCallbacks.animateCollapse();
+ mCallbacks.animateCollapse(msg.arg2);
}
break;
case MSG_SET_SYSTEMUI_VISIBILITY:
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
index 409e684..3a50560 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -76,6 +76,7 @@ import com.android.systemui.recent.RecentTasksLoader;
import com.android.systemui.statusbar.BaseStatusBar;
import com.android.systemui.statusbar.NotificationData;
import com.android.systemui.statusbar.NotificationData.Entry;
+import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.RotationToggle;
import com.android.systemui.statusbar.SignalClusterView;
import com.android.systemui.statusbar.StatusBarIconView;
@@ -360,6 +361,7 @@ public class PhoneStatusBar extends BaseStatusBar {
mClearButton = mStatusBarWindow.findViewById(R.id.clear_all_button);
mClearButton.setOnClickListener(mClearButtonListener);
mClearButton.setAlpha(0f);
+ mClearButton.setVisibility(View.INVISIBLE);
mClearButton.setEnabled(false);
mDateView = (DateView)mStatusBarWindow.findViewById(R.id.date);
mSettingsButton = mStatusBarWindow.findViewById(R.id.settings_button);
@@ -482,7 +484,14 @@ public class PhoneStatusBar extends BaseStatusBar {
@Override
public void showSearchPanel() {
- super.showSearchPanel();
+ // XXX This is a bit of a hack. Since navbar is no longer slippery, we use the
+ // gesture to dismiss the expanded statusbar.
+ if (mExpanded) {
+ animateCollapse();
+ return;
+ } else {
+ super.showSearchPanel();
+ }
WindowManager.LayoutParams lp =
(android.view.WindowManager.LayoutParams) mNavigationBarView.getLayoutParams();
lp.flags &= ~WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;
@@ -505,7 +514,7 @@ public class PhoneStatusBar extends BaseStatusBar {
public int getStatusBarHeight() {
if (mNaturalBarHeight < 0) {
final Resources res = mContext.getResources();
- mNaturalBarHeight =
+ mNaturalBarHeight =
res.getDimensionPixelSize(com.android.internal.R.dimen.status_bar_height);
}
return mNaturalBarHeight;
@@ -521,14 +530,29 @@ public class PhoneStatusBar extends BaseStatusBar {
}
};
+ private int mShowSearchHoldoff = 0;
+ private Runnable mShowSearchPanel = new Runnable() {
+ public void run() {
+ showSearchPanel();
+ }
+ };
+
View.OnTouchListener mHomeSearchActionListener = new View.OnTouchListener() {
public boolean onTouch(View v, MotionEvent event) {
switch(event.getAction()) {
- case MotionEvent.ACTION_DOWN:
- showSearchPanel();
- break;
- }
- return false;
+ case MotionEvent.ACTION_DOWN:
+ if (!shouldDisableNavbarGestures()) {
+ mHandler.removeCallbacks(mShowSearchPanel);
+ mHandler.postDelayed(mShowSearchPanel, mShowSearchHoldoff);
+ }
+ break;
+
+ case MotionEvent.ACTION_UP:
+ case MotionEvent.ACTION_CANCEL:
+ mHandler.removeCallbacks(mShowSearchPanel);
+ break;
+ }
+ return false;
}
};
@@ -673,9 +697,9 @@ public class PhoneStatusBar extends BaseStatusBar {
if (INTRUDER_ALERT_DECAY_MS > 0) {
mHandler.sendEmptyMessageDelayed(MSG_HIDE_INTRUDER, INTRUDER_ALERT_DECAY_MS);
}
- } else
+ } else
*/
-
+
if (notification.notification.fullScreenIntent != null) {
// not immersive & a full-screen alert should be shown
Slog.d(TAG, "Notification has fullScreenIntent; sending fullScreenIntent");
@@ -723,6 +747,8 @@ public class PhoneStatusBar extends BaseStatusBar {
@Override
protected void onConfigurationChanged(Configuration newConfig) {
updateRecentsPanel();
+ mShowSearchHoldoff = mContext.getResources().getInteger(
+ R.integer.config_show_search_delay);
}
private void loadNotificationShade() {
@@ -816,16 +842,31 @@ public class PhoneStatusBar extends BaseStatusBar {
if (mClearButton.isShown()) {
if (clearable != (mClearButton.getAlpha() == 1.0f)) {
- ObjectAnimator.ofFloat(mClearButton, "alpha",
- clearable ? 1.0f : 0.0f)
- .setDuration(250)
- .start();
+ ObjectAnimator clearAnimation = ObjectAnimator.ofFloat(
+ mClearButton, "alpha", clearable ? 1.0f : 0.0f).setDuration(250);
+ clearAnimation.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ if (mClearButton.getAlpha() <= 0.0f) {
+ mClearButton.setVisibility(View.INVISIBLE);
+ }
+ }
+
+ @Override
+ public void onAnimationStart(Animator animation) {
+ if (mClearButton.getAlpha() <= 0.0f) {
+ mClearButton.setVisibility(View.VISIBLE);
+ }
+ }
+ });
+ clearAnimation.start();
}
} else {
mClearButton.setAlpha(clearable ? 1.0f : 0.0f);
+ mClearButton.setVisibility(clearable ? View.VISIBLE : View.INVISIBLE);
}
mClearButton.setEnabled(clearable);
-
+
final View nlo = mStatusBarView.findViewById(R.id.notification_lights_out);
final boolean showDot = (any&&!areLightsOn());
if (showDot != (nlo.getAlpha() == 1.0f)) {
@@ -890,7 +931,7 @@ public class PhoneStatusBar extends BaseStatusBar {
flagdbg.append(((diff & StatusBarManager.DISABLE_CLOCK) != 0) ? "* " : " ");
flagdbg.append(">");
Slog.d(TAG, flagdbg.toString());
-
+
if ((diff & StatusBarManager.DISABLE_SYSTEM_INFO) != 0) {
mIcons.animate().cancel();
if ((state & StatusBarManager.DISABLE_SYSTEM_INFO) != 0) {
@@ -1000,7 +1041,7 @@ public class PhoneStatusBar extends BaseStatusBar {
if (mExpandedVisible) {
return;
}
-
+
mExpandedVisible = true;
mNotificationPanel.setVisibility(View.VISIBLE);
@@ -1032,28 +1073,34 @@ public class PhoneStatusBar extends BaseStatusBar {
}
public void animateCollapse() {
- animateCollapse(false);
+ animateCollapse(CommandQueue.FLAG_EXCLUDE_NONE);
}
- public void animateCollapse(boolean excludeRecents) {
- animateCollapse(excludeRecents, 1.0f);
+ public void animateCollapse(int flags) {
+ animateCollapse(flags, 1.0f);
}
- public void animateCollapse(boolean excludeRecents, float velocityMultiplier) {
+ public void animateCollapse(int flags, float velocityMultiplier) {
if (SPEW) {
Slog.d(TAG, "animateCollapse(): mExpanded=" + mExpanded
+ " mExpandedVisible=" + mExpandedVisible
+ " mExpanded=" + mExpanded
+ " mAnimating=" + mAnimating
+ " mAnimY=" + mAnimY
- + " mAnimVel=" + mAnimVel);
+ + " mAnimVel=" + mAnimVel
+ + " flags=" + flags);
}
- if (!excludeRecents) {
+ if ((flags & CommandQueue.FLAG_EXCLUDE_RECENTS_PANEL) == 0) {
mHandler.removeMessages(MSG_CLOSE_RECENTS_PANEL);
mHandler.sendEmptyMessage(MSG_CLOSE_RECENTS_PANEL);
}
+ if ((flags & CommandQueue.FLAG_EXCLUDE_SEARCH_PANEL) == 0) {
+ mHandler.removeMessages(MSG_CLOSE_SEARCH_PANEL);
+ mHandler.sendEmptyMessage(MSG_CLOSE_SEARCH_PANEL);
+ }
+
if (!mExpandedVisible) {
return;
}
@@ -1195,7 +1242,7 @@ public class PhoneStatusBar extends BaseStatusBar {
//Slog.d(TAG, "y=" + y + " v=" + v + " a=" + a + " t=" + t + " mAnimY=" + mAnimY
// + " mAnimAccel=" + mAnimAccel);
}
-
+
void doRevealAnimation(long frameTimeNanos) {
if (SPEW) {
Slog.d(TAG, "doRevealAnimation: dt=" + (frameTimeNanos - mAnimLastTimeNanos));
@@ -1447,11 +1494,11 @@ public class PhoneStatusBar extends BaseStatusBar {
mTicker.halt();
}
}
-
+
if (mNavigationBarView != null) {
mNavigationBarView.setLowProfile(lightsOut);
}
-
+
setStatusBarLowProfile(lightsOut);
}
@@ -1476,7 +1523,7 @@ public class PhoneStatusBar extends BaseStatusBar {
ObjectAnimator.ofFloat(clock, View.ALPHA, 0.5f)
);
mLightsOutAnimation.setDuration(750);
-
+
mLightsOnAnimation = new AnimatorSet();
mLightsOnAnimation.playTogether(
ObjectAnimator.ofFloat(notifications, View.ALPHA, 1),
@@ -1487,7 +1534,7 @@ public class PhoneStatusBar extends BaseStatusBar {
);
mLightsOnAnimation.setDuration(250);
}
-
+
mLightsOutAnimation.cancel();
mLightsOnAnimation.cancel();
@@ -1500,7 +1547,7 @@ public class PhoneStatusBar extends BaseStatusBar {
private boolean areLightsOn() {
return 0 == (mSystemUiVisibility & View.SYSTEM_UI_FLAG_LOW_PROFILE);
}
-
+
public void setLightsOn(boolean on) {
Log.v(TAG, "setLightsOn(" + on + ")");
if (on) {
@@ -1604,7 +1651,7 @@ public class PhoneStatusBar extends BaseStatusBar {
protected void tick(IBinder key, StatusBarNotification n, boolean firstTime) {
// no ticking in lights-out mode
if (!areLightsOn()) return;
-
+
// Show the ticker if one is requested. Also don't do this
// until status bar window is attached to the window manager,
// because... well, what's the point otherwise? And trying to
@@ -1804,7 +1851,6 @@ public class PhoneStatusBar extends BaseStatusBar {
}
int panelh = 0;
-
final int disph = getExpandedViewMaxHeight();
// If the expanded view is not visible, make sure they're still off screen.
@@ -1915,7 +1961,7 @@ public class PhoneStatusBar extends BaseStatusBar {
}
}
if (snapshot.isEmpty()) {
- animateCollapse(false);
+ animateCollapse(CommandQueue.FLAG_EXCLUDE_NONE);
return;
}
new Thread(new Runnable() {
@@ -1963,7 +2009,7 @@ public class PhoneStatusBar extends BaseStatusBar {
mHandler.postDelayed(new Runnable() {
@Override
public void run() {
- animateCollapse(false);
+ animateCollapse(CommandQueue.FLAG_EXCLUDE_NONE);
}
}, totalDelay + 225);
}
@@ -1990,14 +2036,14 @@ public class PhoneStatusBar extends BaseStatusBar {
String action = intent.getAction();
if (Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)
|| Intent.ACTION_SCREEN_OFF.equals(action)) {
- boolean excludeRecents = false;
+ int flags = CommandQueue.FLAG_EXCLUDE_NONE;
if (Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)) {
String reason = intent.getStringExtra("reason");
- if (reason != null) {
- excludeRecents = reason.equals(SYSTEM_DIALOG_REASON_RECENT_APPS);
+ if (reason != null && reason.equals(SYSTEM_DIALOG_REASON_RECENT_APPS)) {
+ flags |= CommandQueue.FLAG_EXCLUDE_RECENTS_PANEL;
}
}
- animateCollapse(excludeRecents);
+ animateCollapse(flags);
}
else if (Intent.ACTION_CONFIGURATION_CHANGED.equals(action)) {
updateResources();
@@ -2021,7 +2067,7 @@ public class PhoneStatusBar extends BaseStatusBar {
try {
mBarService.onNotificationClear(
mCurrentlyIntrudingNotification.pkg,
- mCurrentlyIntrudingNotification.tag,
+ mCurrentlyIntrudingNotification.tag,
mCurrentlyIntrudingNotification.id);
} catch (android.os.RemoteException ex) {
// oh well
@@ -2077,14 +2123,14 @@ public class PhoneStatusBar extends BaseStatusBar {
mCollapseAccelPx = res.getDimension(R.dimen.collapse_accel);
mFlingGestureMaxXVelocityPx = res.getDimension(R.dimen.fling_gesture_max_x_velocity);
-
+
mNotificationPanelMarginBottomPx
= (int) res.getDimension(R.dimen.notification_panel_margin_bottom);
mNotificationPanelMarginLeftPx
= (int) res.getDimension(R.dimen.notification_panel_margin_left);
mNotificationPanelGravity = res.getInteger(R.integer.notification_panel_layout_gravity);
if (mNotificationPanelGravity <= 0) {
- mNotificationPanelGravity = Gravity.CENTER_VERTICAL | Gravity.TOP;
+ mNotificationPanelGravity = Gravity.CENTER_VERTICAL | Gravity.TOP;
}
if (false) Slog.v(TAG, "updateResources");
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java
index c65f581..584a69e4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java
@@ -1000,7 +1000,7 @@ public class NetworkController extends BroadcastReceiver {
mContentDescriptionPhoneSignal = mContext.getString(
R.string.accessibility_airplane_mode);
mAirplaneIconId = R.drawable.stat_sys_signal_flightmode;
- mDataTypeIconId = 0;
+ mPhoneSignalIconId = mDataSignalIconId = mDataTypeIconId = 0;
// combined values from connected wifi take precedence over airplane mode
if (mWifiConnected) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java
index 10c5dd8..8df9b85 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java
@@ -67,6 +67,7 @@ import com.android.systemui.R;
import com.android.systemui.recent.RecentTasksLoader;
import com.android.systemui.recent.RecentsPanelView;
import com.android.systemui.statusbar.BaseStatusBar;
+import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.DoNotDisturb;
import com.android.systemui.statusbar.NotificationData;
import com.android.systemui.statusbar.SignalClusterView;
@@ -186,13 +187,29 @@ public class TabletStatusBar extends BaseStatusBar implements
private int mNavigationIconHints = 0;
+ private int mShowSearchHoldoff = 0;
+
public Context getContext() { return mContext; }
+ private Runnable mShowSearchPanel = new Runnable() {
+ public void run() {
+ showSearchPanel();
+ }
+ };
+
private View.OnTouchListener mHomeSearchActionListener = new View.OnTouchListener() {
public boolean onTouch(View v, MotionEvent event) {
switch(event.getAction()) {
case MotionEvent.ACTION_DOWN:
- showSearchPanel();
+ if (!shouldDisableNavbarGestures()) {
+ mHandler.removeCallbacks(mShowSearchPanel);
+ mHandler.postDelayed(mShowSearchPanel, mShowSearchHoldoff);
+ }
+ break;
+
+ case MotionEvent.ACTION_UP:
+ case MotionEvent.ACTION_CANCEL:
+ mHandler.removeCallbacks(mShowSearchPanel);
break;
}
return false;
@@ -254,12 +271,12 @@ public class TabletStatusBar extends BaseStatusBar implements
// network icons: either a combo icon that switches between mobile and data, or distinct
// mobile and data icons
- final ImageView mobileRSSI =
+ final ImageView mobileRSSI =
(ImageView)mNotificationPanel.findViewById(R.id.mobile_signal);
if (mobileRSSI != null) {
mNetworkController.addPhoneSignalIconView(mobileRSSI);
}
- final ImageView wifiRSSI =
+ final ImageView wifiRSSI =
(ImageView)mNotificationPanel.findViewById(R.id.wifi_signal);
if (wifiRSSI != null) {
mNetworkController.addWifiIconView(wifiRSSI);
@@ -385,6 +402,8 @@ public class TabletStatusBar extends BaseStatusBar implements
WindowManagerImpl.getDefault().updateViewLayout(mNotificationPanel,
mNotificationPanelParams);
mRecentsPanel.updateValuesFromResources();
+ mShowSearchHoldoff = mContext.getResources().getInteger(
+ R.integer.config_show_search_delay);
}
protected void loadDimens() {
@@ -493,7 +512,7 @@ public class TabletStatusBar extends BaseStatusBar implements
mBluetoothController.addIconView((ImageView)sb.findViewById(R.id.bluetooth));
mNetworkController = new NetworkController(mContext);
- final SignalClusterView signalCluster =
+ final SignalClusterView signalCluster =
(SignalClusterView)sb.findViewById(R.id.signal_cluster);
mNetworkController.addSignalCluster(signalCluster);
@@ -999,20 +1018,31 @@ public class TabletStatusBar extends BaseStatusBar implements
}
public void animateCollapse() {
- animateCollapse(false);
+ animateCollapse(CommandQueue.FLAG_EXCLUDE_NONE);
}
- private void animateCollapse(boolean excludeRecents) {
- mHandler.removeMessages(MSG_CLOSE_NOTIFICATION_PANEL);
- mHandler.sendEmptyMessage(MSG_CLOSE_NOTIFICATION_PANEL);
- if (!excludeRecents) {
+ public void animateCollapse(int flags) {
+ if ((flags & CommandQueue.FLAG_EXCLUDE_NOTIFICATION_PANEL) == 0) {
+ mHandler.removeMessages(MSG_CLOSE_NOTIFICATION_PANEL);
+ mHandler.sendEmptyMessage(MSG_CLOSE_NOTIFICATION_PANEL);
+ }
+ if ((flags & CommandQueue.FLAG_EXCLUDE_RECENTS_PANEL) == 0) {
mHandler.removeMessages(MSG_CLOSE_RECENTS_PANEL);
mHandler.sendEmptyMessage(MSG_CLOSE_RECENTS_PANEL);
}
- mHandler.removeMessages(MSG_CLOSE_INPUT_METHODS_PANEL);
- mHandler.sendEmptyMessage(MSG_CLOSE_INPUT_METHODS_PANEL);
- mHandler.removeMessages(MSG_CLOSE_COMPAT_MODE_PANEL);
- mHandler.sendEmptyMessage(MSG_CLOSE_COMPAT_MODE_PANEL);
+ if ((flags & CommandQueue.FLAG_EXCLUDE_SEARCH_PANEL) == 0) {
+ mHandler.removeMessages(MSG_CLOSE_SEARCH_PANEL);
+ mHandler.sendEmptyMessage(MSG_CLOSE_SEARCH_PANEL);
+ }
+ if ((flags & CommandQueue.FLAG_EXCLUDE_INPUT_METHODS_PANEL) == 0) {
+ mHandler.removeMessages(MSG_CLOSE_INPUT_METHODS_PANEL);
+ mHandler.sendEmptyMessage(MSG_CLOSE_INPUT_METHODS_PANEL);
+ }
+ if ((flags & CommandQueue.FLAG_EXCLUDE_COMPAT_MODE_PANEL) == 0) {
+ mHandler.removeMessages(MSG_CLOSE_COMPAT_MODE_PANEL);
+ mHandler.sendEmptyMessage(MSG_CLOSE_COMPAT_MODE_PANEL);
+ }
+
}
@Override // CommandQueue
@@ -1059,7 +1089,7 @@ public class TabletStatusBar extends BaseStatusBar implements
if (0 != (diff & View.SYSTEM_UI_FLAG_LOW_PROFILE)) {
mHandler.removeMessages(MSG_HIDE_CHROME);
mHandler.removeMessages(MSG_SHOW_CHROME);
- mHandler.sendEmptyMessage(0 == (vis & View.SYSTEM_UI_FLAG_LOW_PROFILE)
+ mHandler.sendEmptyMessage(0 == (vis & View.SYSTEM_UI_FLAG_LOW_PROFILE)
? MSG_SHOW_CHROME : MSG_HIDE_CHROME);
}
@@ -1590,11 +1620,11 @@ public class TabletStatusBar extends BaseStatusBar implements
String action = intent.getAction();
if (Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)
|| Intent.ACTION_SCREEN_OFF.equals(action)) {
- boolean excludeRecents = false;
+ int flags = CommandQueue.FLAG_EXCLUDE_NONE;
if (Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)) {
String reason = intent.getStringExtra("reason");
- if (reason != null) {
- excludeRecents = reason.equals(SYSTEM_DIALOG_REASON_RECENT_APPS);
+ if (reason != null && reason.equals(SYSTEM_DIALOG_REASON_RECENT_APPS)) {
+ flags |= CommandQueue.FLAG_EXCLUDE_RECENTS_PANEL;
}
}
if (Intent.ACTION_SCREEN_OFF.equals(action)) {
@@ -1603,9 +1633,9 @@ public class TabletStatusBar extends BaseStatusBar implements
// TODO: hide other things, like the notification tray,
// with no animation as well
mRecentsPanel.show(false, false);
- excludeRecents = true;
+ flags |= CommandQueue.FLAG_EXCLUDE_RECENTS_PANEL;
}
- animateCollapse(excludeRecents);
+ animateCollapse(flags);
}
}
};
diff --git a/policy/src/com/android/internal/policy/impl/FaceUnlock.java b/policy/src/com/android/internal/policy/impl/FaceUnlock.java
index 737ea47..22b854e 100644
--- a/policy/src/com/android/internal/policy/impl/FaceUnlock.java
+++ b/policy/src/com/android/internal/policy/impl/FaceUnlock.java
@@ -468,7 +468,8 @@ public class FaceUnlock implements BiometricSensorUnlock, Handler.Callback {
if (!mServiceRunning) {
Log.d(TAG, "Starting Face Unlock");
try {
- mService.startUi(windowToken, x, y, w, h, false);
+ mService.startUi(windowToken, x, y, w, h,
+ mLockPatternUtils.isBiometricWeakLivelinessEnabled());
} catch (RemoteException e) {
Log.e(TAG, "Caught exception starting Face Unlock: " + e.toString());
return;
diff --git a/policy/src/com/android/internal/policy/impl/GlobalActions.java b/policy/src/com/android/internal/policy/impl/GlobalActions.java
index aa73de4..fc187ce 100644
--- a/policy/src/com/android/internal/policy/impl/GlobalActions.java
+++ b/policy/src/com/android/internal/policy/impl/GlobalActions.java
@@ -28,7 +28,9 @@ import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.UserInfo;
+import android.database.ContentObserver;
import android.media.AudioManager;
+import android.net.ConnectivityManager;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
@@ -73,7 +75,7 @@ class GlobalActions implements DialogInterface.OnDismissListener, DialogInterfac
private ArrayList<Action> mItems;
private AlertDialog mDialog;
- private SilentModeAction mSilentModeAction;
+ private Action mSilentModeAction;
private ToggleAction mAirplaneModeOn;
private MyAdapter mAdapter;
@@ -82,6 +84,8 @@ class GlobalActions implements DialogInterface.OnDismissListener, DialogInterfac
private boolean mDeviceProvisioned = false;
private ToggleAction.State mAirplaneState = ToggleAction.State.Off;
private boolean mIsWaitingForEcmExit = false;
+ private boolean mHasTelephony;
+ private boolean mHasVibrator;
private IWindowManager mIWindowManager;
@@ -104,6 +108,14 @@ class GlobalActions implements DialogInterface.OnDismissListener, DialogInterfac
TelephonyManager telephonyManager =
(TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
telephonyManager.listen(mPhoneStateListener, PhoneStateListener.LISTEN_SERVICE_STATE);
+ ConnectivityManager cm = (ConnectivityManager)
+ context.getSystemService(Context.CONNECTIVITY_SERVICE);
+ mHasTelephony = cm.isNetworkSupported(ConnectivityManager.TYPE_MOBILE);
+ mContext.getContentResolver().registerContentObserver(
+ Settings.System.getUriFor(Settings.System.AIRPLANE_MODE_ON), true,
+ mAirplaneModeObserver);
+ Vibrator vibrator = (Vibrator) mContext.getSystemService(Context.VIBRATOR_SERVICE);
+ mHasVibrator = vibrator != null && vibrator.hasVibrator();
}
/**
@@ -130,13 +142,18 @@ class GlobalActions implements DialogInterface.OnDismissListener, DialogInterfac
mDialog.show();
mDialog.getWindow().getDecorView().setSystemUiVisibility(View.STATUS_BAR_DISABLE_EXPAND);
}
+
/**
* Create the global actions dialog.
* @return A new dialog.
*/
private AlertDialog createDialog() {
- mSilentModeAction = new SilentModeAction(mContext, mAudioManager, mHandler);
-
+ // Simple toggle style if there's no vibrator, otherwise use a tri-state
+ if (!mHasVibrator) {
+ mSilentModeAction = new SilentModeToggleAction();
+ } else {
+ mSilentModeAction = new SilentModeTriStateAction(mContext, mAudioManager, mHandler);
+ }
mAirplaneModeOn = new ToggleAction(
R.drawable.ic_lock_airplane_mode,
R.drawable.ic_lock_airplane_mode_off,
@@ -145,7 +162,7 @@ class GlobalActions implements DialogInterface.OnDismissListener, DialogInterfac
R.string.global_actions_airplane_mode_off_status) {
void onToggle(boolean on) {
- if (Boolean.parseBoolean(
+ if (mHasTelephony && Boolean.parseBoolean(
SystemProperties.get(TelephonyProperties.PROPERTY_INECM_MODE))) {
mIsWaitingForEcmExit = true;
// Launch ECM exit dialog
@@ -160,6 +177,8 @@ class GlobalActions implements DialogInterface.OnDismissListener, DialogInterfac
@Override
protected void changeStateFromPress(boolean buttonOn) {
+ if (!mHasTelephony) return;
+
// In ECM mode airplane state cannot be changed
if (!(Boolean.parseBoolean(
SystemProperties.get(TelephonyProperties.PROPERTY_INECM_MODE)))) {
@@ -176,6 +195,7 @@ class GlobalActions implements DialogInterface.OnDismissListener, DialogInterfac
return false;
}
};
+ onAirplaneModeChanged();
mItems = new ArrayList<Action>();
@@ -247,6 +267,7 @@ class GlobalActions implements DialogInterface.OnDismissListener, DialogInterfac
mItems.add(switchToUser);
}
}
+
mAdapter = new MyAdapter();
final AlertDialog.Builder ab = new AlertDialog.Builder(mContext);
@@ -273,8 +294,7 @@ class GlobalActions implements DialogInterface.OnDismissListener, DialogInterfac
}
private void prepareDialog() {
- final boolean silentModeOn =
- mAudioManager.getRingerMode() != AudioManager.RINGER_MODE_NORMAL;
+ refreshSilentMode();
mAirplaneModeOn.updateState(mAirplaneState);
mAdapter.notifyDataSetChanged();
if (mKeyguardShowing) {
@@ -288,6 +308,15 @@ class GlobalActions implements DialogInterface.OnDismissListener, DialogInterfac
}
}
+ private void refreshSilentMode() {
+ if (!mHasVibrator) {
+ final boolean silentModeOn =
+ mAudioManager.getRingerMode() != AudioManager.RINGER_MODE_NORMAL;
+ ((ToggleAction)mSilentModeAction).updateState(
+ silentModeOn ? ToggleAction.State.On : ToggleAction.State.Off);
+ }
+ }
+
/** {@inheritDoc} */
public void onDismiss(DialogInterface dialog) {
if (SHOW_SILENT_TOGGLE) {
@@ -297,7 +326,7 @@ class GlobalActions implements DialogInterface.OnDismissListener, DialogInterfac
/** {@inheritDoc} */
public void onClick(DialogInterface dialog, int which) {
- if (!(mAdapter.getItem(which) instanceof SilentModeAction)) {
+ if (!(mAdapter.getItem(which) instanceof SilentModeTriStateAction)) {
dialog.dismiss();
}
mAdapter.getItem(which).onPress();
@@ -495,12 +524,12 @@ class GlobalActions implements DialogInterface.OnDismissListener, DialogInterfac
*/
public ToggleAction(int enabledIconResId,
int disabledIconResid,
- int essage,
+ int message,
int enabledStatusMessageResId,
int disabledStatusMessageResId) {
mEnabledIconResId = enabledIconResId;
mDisabledIconResid = disabledIconResid;
- mMessageResId = essage;
+ mMessageResId = message;
mEnabledStatusMessageResId = enabledStatusMessageResId;
mDisabledStatusMessageResId = disabledStatusMessageResId;
}
@@ -583,21 +612,44 @@ class GlobalActions implements DialogInterface.OnDismissListener, DialogInterfac
}
}
- private static class SilentModeAction implements Action, View.OnClickListener {
+ private class SilentModeToggleAction extends ToggleAction {
+ public SilentModeToggleAction() {
+ super(R.drawable.ic_audio_vol_mute,
+ R.drawable.ic_audio_vol,
+ R.string.global_action_toggle_silent_mode,
+ R.string.global_action_silent_mode_on_status,
+ R.string.global_action_silent_mode_off_status);
+ }
+
+ void onToggle(boolean on) {
+ if (on) {
+ mAudioManager.setRingerMode(AudioManager.RINGER_MODE_SILENT);
+ } else {
+ mAudioManager.setRingerMode(AudioManager.RINGER_MODE_NORMAL);
+ }
+ }
+
+ public boolean showDuringKeyguard() {
+ return true;
+ }
+
+ public boolean showBeforeProvisioning() {
+ return false;
+ }
+ }
+
+ private static class SilentModeTriStateAction implements Action, View.OnClickListener {
private final int[] ITEM_IDS = { R.id.option1, R.id.option2, R.id.option3 };
private final AudioManager mAudioManager;
private final Handler mHandler;
- private final boolean mHasVibrator;
private final Context mContext;
- SilentModeAction(Context context, AudioManager audioManager, Handler handler) {
+ SilentModeTriStateAction(Context context, AudioManager audioManager, Handler handler) {
mAudioManager = audioManager;
mHandler = handler;
mContext = context;
- Vibrator vibrator = (Vibrator) mContext.getSystemService(Context.VIBRATOR_SERVICE);
- mHasVibrator = vibrator != null && vibrator.hasVibrator();
}
private int ringerModeToIndex(int ringerMode) {
@@ -621,9 +673,6 @@ class GlobalActions implements DialogInterface.OnDismissListener, DialogInterfac
// Set up click handler
itemView.setTag(i);
itemView.setOnClickListener(this);
- if (itemView.getId() == R.id.option2 && !mHasVibrator) {
- itemView.setVisibility(View.GONE);
- }
}
return v;
}
@@ -683,6 +732,7 @@ class GlobalActions implements DialogInterface.OnDismissListener, DialogInterfac
PhoneStateListener mPhoneStateListener = new PhoneStateListener() {
@Override
public void onServiceStateChanged(ServiceState serviceState) {
+ if (!mHasTelephony) return;
final boolean inAirplaneMode = serviceState.getState() == ServiceState.STATE_POWER_OFF;
mAirplaneState = inAirplaneMode ? ToggleAction.State.On : ToggleAction.State.Off;
mAirplaneModeOn.updateState(mAirplaneState);
@@ -699,6 +749,13 @@ class GlobalActions implements DialogInterface.OnDismissListener, DialogInterfac
}
};
+ private ContentObserver mAirplaneModeObserver = new ContentObserver(new Handler()) {
+ @Override
+ public void onChange(boolean selfChange) {
+ onAirplaneModeChanged();
+ }
+ };
+
private static final int MESSAGE_DISMISS = 0;
private static final int MESSAGE_REFRESH = 1;
private static final int MESSAGE_SHOW = 2;
@@ -713,6 +770,7 @@ class GlobalActions implements DialogInterface.OnDismissListener, DialogInterfac
}
break;
case MESSAGE_REFRESH:
+ refreshSilentMode();
mAdapter.notifyDataSetChanged();
break;
case MESSAGE_SHOW:
@@ -722,6 +780,18 @@ class GlobalActions implements DialogInterface.OnDismissListener, DialogInterfac
}
};
+ private void onAirplaneModeChanged() {
+ // Let the service state callbacks handle the state.
+ if (mHasTelephony) return;
+
+ boolean airplaneModeOn = Settings.System.getInt(
+ mContext.getContentResolver(),
+ Settings.System.AIRPLANE_MODE_ON,
+ 0) == 1;
+ mAirplaneState = airplaneModeOn ? ToggleAction.State.On : ToggleAction.State.Off;
+ mAirplaneModeOn.updateState(mAirplaneState);
+ }
+
/**
* Change the airplane mode system setting
*/
@@ -734,6 +804,9 @@ class GlobalActions implements DialogInterface.OnDismissListener, DialogInterfac
intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING);
intent.putExtra("state", on);
mContext.sendBroadcast(intent);
+ if (!mHasTelephony) {
+ mAirplaneState = on ? ToggleAction.State.On : ToggleAction.State.Off;
+ }
}
private IWindowManager getWindowManager() {
diff --git a/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java b/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java
index 049e6ac..518d8e9 100644
--- a/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java
+++ b/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java
@@ -532,11 +532,6 @@ public class LockPatternKeyguardView extends KeyguardViewBase {
if (DEBUG) Log.d(TAG, "screen off");
mScreenOn = false;
mForgotPattern = false;
- if (mBiometricUnlock != null) {
- mSuppressBiometricUnlock =
- mUpdateMonitor.getPhoneState() != TelephonyManager.CALL_STATE_IDLE
- || mHasDialog;
- }
// Emulate activity life-cycle for both lock and unlock screen.
if (mLockScreen != null) {
@@ -991,6 +986,17 @@ public class LockPatternKeyguardView extends KeyguardViewBase {
restartBiometricUnlock = mBiometricUnlock.stop();
}
+ // Prevents biometric unlock from coming up immediately after a phone call or if there
+ // is a dialog on top of lockscreen. It is only updated if the screen is off because if the
+ // screen is on it's either because of an orientation change, or when it first boots.
+ // In both those cases, we don't want to override the current value of
+ // mSuppressBiometricUnlock and instead want to use the previous value.
+ if (!mScreenOn) {
+ mSuppressBiometricUnlock =
+ mUpdateMonitor.getPhoneState() != TelephonyManager.CALL_STATE_IDLE
+ || mHasDialog;
+ }
+
// If the biometric unlock is not being used, we don't bother constructing it. Then we can
// simply check if it is null when deciding whether we should make calls to it.
mBiometricUnlock = null;
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
index a99ae26..1033296 100755
--- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
@@ -1798,7 +1798,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
}
}
if (down) {
- if (!mHomePressed) {
+ if (!mHomePressed && mLongPressOnHomeBehavior == LONG_PRESS_HOME_RECENT_SYSTEM_UI) {
try {
mStatusBarService.preloadRecentApps();
} catch (RemoteException e) {
@@ -2278,7 +2278,12 @@ public class PhoneWindowManager implements WindowManagerPolicy {
// It's a system nav bar or a portrait screen; nav bar goes on bottom.
int top = displayHeight - mNavigationBarHeightForRotation[displayRotation];
if (mHdmiPlugged) {
- if (top > mExternalDisplayHeight) {
+ // Move the nav bar up if the external display is the same aspect ratio
+ // but shorter. This avoids clipping on the external display.
+ boolean sameAspect = mExternalDisplayHeight > 0 && displayHeight > 0
+ && ((float) mExternalDisplayWidth / mExternalDisplayHeight > 1)
+ == ((float) displayWidth / displayHeight > 1);
+ if (sameAspect && top > mExternalDisplayHeight) {
top = mExternalDisplayHeight;
}
}
diff --git a/services/input/InputDispatcher.cpp b/services/input/InputDispatcher.cpp
index 1062d68..c8e11c2 100644
--- a/services/input/InputDispatcher.cpp
+++ b/services/input/InputDispatcher.cpp
@@ -1226,27 +1226,36 @@ int32_t InputDispatcher::findTouchedWindowTargetsLocked(nsecs_t currentTime,
isSplit = true;
} else if (isSplit) {
// New window does not support splitting but we have already split events.
- // Assign the pointer to the first foreground window we find.
- // (May be NULL which is why we put this code block before the next check.)
- newTouchedWindowHandle = mTempTouchState.getFirstForegroundWindowHandle();
+ // Ignore the new window.
+ newTouchedWindowHandle = NULL;
}
- // If we did not find a touched window then fail.
+ // Handle the case where we did not find a window.
if (newTouchedWindowHandle == NULL) {
- if (mFocusedApplicationHandle != NULL) {
+ // Try to assign the pointer to the first foreground window we find, if there is one.
+ newTouchedWindowHandle = mTempTouchState.getFirstForegroundWindowHandle();
+ if (newTouchedWindowHandle == NULL) {
+ // There is no touched window. If this is an initial down event
+ // then wait for a window to appear that will handle the touch. This is
+ // to ensure that we report an ANR in the case where an application has started
+ // but not yet put up a window and the user is starting to get impatient.
+ if (maskedAction == AMOTION_EVENT_ACTION_DOWN
+ && mFocusedApplicationHandle != NULL) {
#if DEBUG_FOCUS
- ALOGD("Waiting because there is no touched window but there is a "
- "focused application that may eventually add a new window: %s.",
- getApplicationWindowLabelLocked(mFocusedApplicationHandle, NULL).string());
+ ALOGD("Waiting because there is no touched window but there is a "
+ "focused application that may eventually add a new window: %s.",
+ getApplicationWindowLabelLocked(
+ mFocusedApplicationHandle, NULL).string());
#endif
- injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
- mFocusedApplicationHandle, NULL, nextWakeupTime);
- goto Unresponsive;
- }
+ injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
+ mFocusedApplicationHandle, NULL, nextWakeupTime);
+ goto Unresponsive;
+ }
- ALOGI("Dropping event because there is no touched window or focused application.");
- injectionResult = INPUT_EVENT_INJECTION_FAILED;
- goto Failed;
+ ALOGI("Dropping event because there is no touched window.");
+ injectionResult = INPUT_EVENT_INJECTION_FAILED;
+ goto Failed;
+ }
}
// Set target flags.
diff --git a/services/java/com/android/server/LocationManagerService.java b/services/java/com/android/server/LocationManagerService.java
index 1e707b2..985249d 100644
--- a/services/java/com/android/server/LocationManagerService.java
+++ b/services/java/com/android/server/LocationManagerService.java
@@ -26,7 +26,11 @@ import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.ServiceConnection;
+import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.content.pm.PackageManager.NameNotFoundException;
+import android.content.pm.Signature;
import android.content.res.Resources;
import android.database.Cursor;
import android.location.Address;
@@ -123,8 +127,9 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
private static boolean sProvidersLoaded = false;
private final Context mContext;
- private final String mNetworkLocationProviderPackageName;
- private final String mGeocodeProviderPackageName;
+ private PackageManager mPackageManager; // final after initialize()
+ private String mNetworkLocationProviderPackageName; // only used on handler thread
+ private String mGeocodeProviderPackageName; // only used on handler thread
private GeocoderProxy mGeocodeProvider;
private IGpsStatusProvider mGpsStatusProvider;
private INetInitiatedListener mNetInitiatedListener;
@@ -490,36 +495,91 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
addProvider(passiveProvider);
mEnabledProviders.add(passiveProvider.getName());
- // initialize external network location and geocoder services
- PackageManager pm = mContext.getPackageManager();
- if (mNetworkLocationProviderPackageName != null &&
- pm.resolveService(new Intent(mNetworkLocationProviderPackageName), 0) != null) {
- mNetworkLocationProvider =
- new LocationProviderProxy(mContext, LocationManager.NETWORK_PROVIDER,
- mNetworkLocationProviderPackageName, mLocationHandler);
-
- addProvider(mNetworkLocationProvider);
+ // initialize external network location and geocoder services.
+ // The initial value of mNetworkLocationProviderPackageName and
+ // mGeocodeProviderPackageName is just used to determine what
+ // signatures future mNetworkLocationProviderPackageName and
+ // mGeocodeProviderPackageName packages must have. So alternate
+ // providers can be installed under a different package name
+ // so long as they have the same signature as the original
+ // provider packages.
+ if (mNetworkLocationProviderPackageName != null) {
+ String packageName = findBestPackage(LocationProviderProxy.SERVICE_ACTION,
+ mNetworkLocationProviderPackageName);
+ if (packageName != null) {
+ mNetworkLocationProvider = new LocationProviderProxy(mContext,
+ LocationManager.NETWORK_PROVIDER,
+ packageName, mLocationHandler);
+ mNetworkLocationProviderPackageName = packageName;
+ addProvider(mNetworkLocationProvider);
+ }
}
-
- if (mGeocodeProviderPackageName != null &&
- pm.resolveService(new Intent(mGeocodeProviderPackageName), 0) != null) {
- mGeocodeProvider = new GeocoderProxy(mContext, mGeocodeProviderPackageName);
+ if (mGeocodeProviderPackageName != null) {
+ String packageName = findBestPackage(GeocoderProxy.SERVICE_ACTION,
+ mGeocodeProviderPackageName);
+ if (packageName != null) {
+ mGeocodeProvider = new GeocoderProxy(mContext, packageName);
+ mGeocodeProviderPackageName = packageName;
+ }
}
updateProvidersLocked();
}
/**
+ * Pick the best (network location provider or geocode provider) package.
+ * The best package:
+ * - implements serviceIntentName
+ * - has signatures that match that of sigPackageName
+ * - has the highest version value in a meta-data field in the service component
+ */
+ String findBestPackage(String serviceIntentName, String sigPackageName) {
+ Intent intent = new Intent(serviceIntentName);
+ List<ResolveInfo> infos = mPackageManager.queryIntentServices(intent,
+ PackageManager.GET_META_DATA);
+ if (infos == null) return null;
+
+ int bestVersion = Integer.MIN_VALUE;
+ String bestPackage = null;
+ for (ResolveInfo info : infos) {
+ String packageName = info.serviceInfo.packageName;
+ // check signature
+ if (mPackageManager.checkSignatures(packageName, sigPackageName) !=
+ PackageManager.SIGNATURE_MATCH) {
+ Slog.w(TAG, packageName + " implements " + serviceIntentName +
+ " but its signatures don't match those in " + sigPackageName +
+ ", ignoring");
+ continue;
+ }
+ // read version
+ int version = 0;
+ if (info.serviceInfo.metaData != null) {
+ version = info.serviceInfo.metaData.getInt("version", 0);
+ }
+ if (LOCAL_LOGV) Slog.v(TAG, packageName + " implements " + serviceIntentName +
+ " with version " + version);
+ if (version > bestVersion) {
+ bestVersion = version;
+ bestPackage = packageName;
+ }
+ }
+
+ return bestPackage;
+ }
+
+ /**
* @param context the context that the LocationManagerService runs in
*/
public LocationManagerService(Context context) {
super();
mContext = context;
Resources resources = context.getResources();
+
mNetworkLocationProviderPackageName = resources.getString(
- com.android.internal.R.string.config_networkLocationProvider);
+ com.android.internal.R.string.config_networkLocationProviderPackageName);
mGeocodeProviderPackageName = resources.getString(
- com.android.internal.R.string.config_geocodeProvider);
+ com.android.internal.R.string.config_geocodeProviderPackageName);
+
mPackageMonitor.register(context, null, true);
if (LOCAL_LOGV) {
@@ -537,6 +597,7 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
// Create a wake lock, needs to be done before calling loadProviders() below
PowerManager powerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
mWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, WAKELOCK_KEY);
+ mPackageManager = mContext.getPackageManager();
// Load providers
loadProviders();
@@ -1886,16 +1947,33 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
}
} else if (msg.what == MESSAGE_PACKAGE_UPDATED) {
String packageName = (String) msg.obj;
- String packageDot = packageName + ".";
- // reconnect to external providers after their packages have been updated
- if (mNetworkLocationProvider != null &&
- mNetworkLocationProviderPackageName.startsWith(packageDot)) {
- mNetworkLocationProvider.reconnect();
+ // reconnect to external providers if there is a better package
+ if (mNetworkLocationProviderPackageName != null &&
+ mPackageManager.resolveService(
+ new Intent(LocationProviderProxy.SERVICE_ACTION)
+ .setPackage(packageName), 0) != null) {
+ // package implements service, perform full check
+ String bestPackage = findBestPackage(
+ LocationProviderProxy.SERVICE_ACTION,
+ mNetworkLocationProviderPackageName);
+ if (packageName.equals(bestPackage)) {
+ mNetworkLocationProvider.reconnect(bestPackage);
+ mNetworkLocationProviderPackageName = packageName;
+ }
}
- if (mGeocodeProvider != null &&
- mGeocodeProviderPackageName.startsWith(packageDot)) {
- mGeocodeProvider.reconnect();
+ if (mGeocodeProviderPackageName != null &&
+ mPackageManager.resolveService(
+ new Intent(GeocoderProxy.SERVICE_ACTION)
+ .setPackage(packageName), 0) != null) {
+ // package implements service, perform full check
+ String bestPackage = findBestPackage(
+ GeocoderProxy.SERVICE_ACTION,
+ mGeocodeProviderPackageName);
+ if (packageName.equals(bestPackage)) {
+ mGeocodeProvider.reconnect(bestPackage);
+ mGeocodeProviderPackageName = packageName;
+ }
}
}
} catch (Exception e) {
@@ -2004,6 +2082,11 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
// Called by main thread; divert work to LocationWorker.
Message.obtain(mLocationHandler, MESSAGE_PACKAGE_UPDATED, packageName).sendToTarget();
}
+ @Override
+ public void onPackageAdded(String packageName, int uid) {
+ // Called by main thread; divert work to LocationWorker.
+ Message.obtain(mLocationHandler, MESSAGE_PACKAGE_UPDATED, packageName).sendToTarget();
+ }
};
// Wake locks
diff --git a/services/java/com/android/server/TextServicesManagerService.java b/services/java/com/android/server/TextServicesManagerService.java
index c7b336f..c74dd00 100644
--- a/services/java/com/android/server/TextServicesManagerService.java
+++ b/services/java/com/android/server/TextServicesManagerService.java
@@ -198,7 +198,7 @@ public class TextServicesManagerService extends ITextServicesManager.Stub {
}
// TODO: Respect allowImplicitlySelectedSubtype
- // TODO: Save SpellCheckerSubtype by supported languages.
+ // TODO: Save SpellCheckerSubtype by supported languages by looking at "locale".
@Override
public SpellCheckerSubtype getCurrentSpellCheckerSubtype(
String locale, boolean allowImplicitlySelectedSubtype) {
@@ -250,10 +250,10 @@ public class TextServicesManagerService extends ITextServicesManager.Stub {
for (int i = 0; i < sci.getSubtypeCount(); ++i) {
final SpellCheckerSubtype scs = sci.getSubtypeAt(i);
if (hashCode == 0) {
- if (candidateLocale.equals(locale)) {
+ final String scsLocale = scs.getLocale();
+ if (candidateLocale.equals(scsLocale)) {
return scs;
} else if (candidate == null) {
- final String scsLocale = scs.getLocale();
if (candidateLocale.length() >= 2 && scsLocale.length() >= 2
&& candidateLocale.startsWith(scsLocale)) {
// Fall back to the applicable language
diff --git a/services/java/com/android/server/UiModeManagerService.java b/services/java/com/android/server/UiModeManagerService.java
index c936ef9..d1f92a7 100644
--- a/services/java/com/android/server/UiModeManagerService.java
+++ b/services/java/com/android/server/UiModeManagerService.java
@@ -65,7 +65,7 @@ class UiModeManagerService extends IUiModeManager.Stub {
// Enable launching of applications when entering the dock.
private static final boolean ENABLE_LAUNCH_CAR_DOCK_APP = true;
- private static final boolean ENABLE_LAUNCH_DESK_DOCK_APP = false;
+ private static final boolean ENABLE_LAUNCH_DESK_DOCK_APP = true;
private static final int MSG_UPDATE_TWILIGHT = 0;
private static final int MSG_ENABLE_LOCATION_UPDATES = 1;
@@ -120,7 +120,7 @@ class UiModeManagerService extends IUiModeManager.Stub {
| Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
return intent;
}
-
+
// The broadcast receiver which receives the result of the ordered broadcast sent when
// the dock state changes. The original ordered broadcast is sent with an initial result
// code of RESULT_OK. If any of the registered broadcast receivers changes this value, e.g.,
@@ -130,7 +130,7 @@ class UiModeManagerService extends IUiModeManager.Stub {
public void onReceive(Context context, Intent intent) {
if (getResultCode() != Activity.RESULT_OK) {
if (LOG) {
- Slog.v(TAG, "Handling broadcast result for action " + intent.getAction()
+ Slog.v(TAG, "Handling broadcast result for action " + intent.getAction()
+ ": canceled: " + getResultCode());
}
return;
@@ -138,7 +138,7 @@ class UiModeManagerService extends IUiModeManager.Stub {
final int enableFlags = intent.getIntExtra("enableFlags", 0);
final int disableFlags = intent.getIntExtra("disableFlags", 0);
-
+
synchronized (mLock) {
// Launch a dock activity
String category = null;
@@ -166,15 +166,15 @@ class UiModeManagerService extends IUiModeManager.Stub {
if (LOG) {
Slog.v(TAG, String.format(
- "Handling broadcast result for action %s: enable=0x%08x disable=0x%08x category=%s",
+ "Handling broadcast result for action %s: enable=0x%08x disable=0x%08x category=%s",
intent.getAction(), enableFlags, disableFlags, category));
}
-
+
if (category != null) {
// This is the new activity that will serve as home while
// we are in care mode.
Intent homeIntent = buildHomeIntent(category);
-
+
// Now we are going to be careful about switching the
// configuration and starting the activity -- we need to
// do this in a specific order under control of the
@@ -479,8 +479,8 @@ class UiModeManagerService extends IUiModeManager.Stub {
}
if (LOG) {
- Slog.d(TAG,
- "updateConfigurationLocked: mDockState=" + mDockState
+ Slog.d(TAG,
+ "updateConfigurationLocked: mDockState=" + mDockState
+ "; mCarMode=" + mCarModeEnabled
+ "; mNightMode=" + mNightMode
+ "; uiMode=" + uiMode);
@@ -657,7 +657,7 @@ class UiModeManagerService extends IUiModeManager.Stub {
boolean mNetworkListenerEnabled;
boolean mDidFirstInit;
long mLastNetworkRegisterTime = -MIN_LOCATION_UPDATE_MS;
-
+
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
@@ -682,12 +682,12 @@ class UiModeManagerService extends IUiModeManager.Stub {
// since we last requested an update.
return;
}
-
+
// Unregister the current location monitor, so we can
// register a new one for it to get an immediate update.
mNetworkListenerEnabled = false;
mLocationManager.removeUpdates(mEmptyLocationListener);
-
+
// Fall through to re-register listener.
case MSG_ENABLE_LOCATION_UPDATES:
// enable network provider to receive at least location updates for a given
diff --git a/services/java/com/android/server/WiredAccessoryObserver.java b/services/java/com/android/server/WiredAccessoryObserver.java
index 53d1f0e..96ac493 100644
--- a/services/java/com/android/server/WiredAccessoryObserver.java
+++ b/services/java/com/android/server/WiredAccessoryObserver.java
@@ -139,11 +139,14 @@ class WiredAccessoryObserver extends UEventObserver {
private final Context mContext;
private final WakeLock mWakeLock; // held while there is a pending route change
+ private final AudioManager mAudioManager;
+
public WiredAccessoryObserver(Context context) {
mContext = context;
PowerManager pm = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "WiredAccessoryObserver");
mWakeLock.setReferenceCounted(false);
+ mAudioManager = (AudioManager)context.getSystemService(Context.AUDIO_SERVICE);
context.registerReceiver(new BootCompletedReceiver(),
new IntentFilter(Intent.ACTION_BOOT_COMPLETED), null, null);
@@ -250,106 +253,65 @@ class WiredAccessoryObserver extends UEventObserver {
mPrevHeadsetState = mHeadsetState;
mHeadsetState = headsetState;
- if (headsetState == 0) {
- if (mContext.getResources().getBoolean(
- com.android.internal.R.bool.config_sendAudioBecomingNoisy)) {
- Intent intent = new Intent(AudioManager.ACTION_AUDIO_BECOMING_NOISY);
- mContext.sendBroadcast(intent);
- }
-
- // It can take hundreds of ms flush the audio pipeline after
- // apps pause audio playback, but audio route changes are
- // immediate, so delay the route change by 1000ms.
- // This could be improved once the audio sub-system provides an
- // interface to clear the audio pipeline.
- delay = 1000;
- } else {
- // Insert the same delay for headset connection so that the connection event is not
- // broadcast before the disconnection event in case of fast removal/insertion
- if (mHandler.hasMessages(0)) {
- delay = 1000;
- }
- }
mWakeLock.acquire();
- mHandler.sendMessageDelayed(mHandler.obtainMessage(0,
- mHeadsetState,
- mPrevHeadsetState,
- mHeadsetName),
- delay);
+ mHandler.sendMessage(mHandler.obtainMessage(0,
+ mHeadsetState,
+ mPrevHeadsetState,
+ mHeadsetName));
}
- private synchronized final void sendIntents(int headsetState, int prevHeadsetState, String headsetName) {
+ private synchronized final void setDevicesState(int headsetState,
+ int prevHeadsetState,
+ String headsetName) {
int allHeadsets = SUPPORTED_HEADSETS;
for (int curHeadset = 1; allHeadsets != 0; curHeadset <<= 1) {
if ((curHeadset & allHeadsets) != 0) {
- sendIntent(curHeadset, headsetState, prevHeadsetState, headsetName);
+ setDeviceState(curHeadset, headsetState, prevHeadsetState, headsetName);
allHeadsets &= ~curHeadset;
}
}
}
- private final void sendIntent(int headset, int headsetState, int prevHeadsetState, String headsetName) {
+ private final void setDeviceState(int headset,
+ int headsetState,
+ int prevHeadsetState,
+ String headsetName) {
if ((headsetState & headset) != (prevHeadsetState & headset)) {
+ int device;
+ int state;
- int state = 0;
if ((headsetState & headset) != 0) {
state = 1;
+ } else {
+ state = 0;
}
- if((headset == BIT_USB_HEADSET_ANLG) || (headset == BIT_USB_HEADSET_DGTL) ||
- (headset == BIT_HDMI_AUDIO)) {
- Intent intent;
-
- // Pack up the values and broadcast them to everyone
- if (headset == BIT_USB_HEADSET_ANLG) {
- intent = new Intent(Intent.ACTION_ANALOG_AUDIO_DOCK_PLUG);
- intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
- intent.putExtra("state", state);
- intent.putExtra("name", headsetName);
- ActivityManagerNative.broadcastStickyIntent(intent, null);
- } else if (headset == BIT_USB_HEADSET_DGTL) {
- intent = new Intent(Intent.ACTION_DIGITAL_AUDIO_DOCK_PLUG);
- intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
- intent.putExtra("state", state);
- intent.putExtra("name", headsetName);
- ActivityManagerNative.broadcastStickyIntent(intent, null);
- } else if (headset == BIT_HDMI_AUDIO) {
- intent = new Intent(Intent.ACTION_HDMI_AUDIO_PLUG);
- intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
- intent.putExtra("state", state);
- intent.putExtra("name", headsetName);
- ActivityManagerNative.broadcastStickyIntent(intent, null);
- }
- if (LOG) Slog.v(TAG, "Intent.ACTION_USB_HEADSET_PLUG: state: "+state+" name: "+headsetName);
- // TODO: Should we require a permission?
+ if (headset == BIT_HEADSET) {
+ device = AudioManager.DEVICE_OUT_WIRED_HEADSET;
+ } else if (headset == BIT_HEADSET_NO_MIC){
+ device = AudioManager.DEVICE_OUT_WIRED_HEADPHONE;
+ } else if (headset == BIT_USB_HEADSET_ANLG) {
+ device = AudioManager.DEVICE_OUT_ANLG_DOCK_HEADSET;
+ } else if (headset == BIT_USB_HEADSET_DGTL) {
+ device = AudioManager.DEVICE_OUT_DGTL_DOCK_HEADSET;
+ } else if (headset == BIT_HDMI_AUDIO) {
+ device = AudioManager.DEVICE_OUT_AUX_DIGITAL;
+ } else {
+ Slog.e(TAG, "setDeviceState() invalid headset type: "+headset);
+ return;
}
- if((headset == BIT_HEADSET) || (headset == BIT_HEADSET_NO_MIC)) {
- // Pack up the values and broadcast them to everyone
- Intent intent = new Intent(Intent.ACTION_HEADSET_PLUG);
- intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
- //int state = 0;
- int microphone = 0;
+ if (LOG)
+ Slog.v(TAG, "device "+headsetName+((state == 1) ? " connected" : " disconnected"));
- if ((headset & HEADSETS_WITH_MIC) != 0) {
- microphone = 1;
- }
-
- intent.putExtra("state", state);
- intent.putExtra("name", headsetName);
- intent.putExtra("microphone", microphone);
-
- if (LOG) Slog.v(TAG, "Intent.ACTION_HEADSET_PLUG: state: "+state+" name: "+headsetName+" mic: "+microphone);
- // TODO: Should we require a permission?
- ActivityManagerNative.broadcastStickyIntent(intent, null);
- }
+ mAudioManager.setWiredDeviceConnectionState(device, state, headsetName);
}
}
private final Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
- sendIntents(msg.arg1, msg.arg2, (String)msg.obj);
+ setDevicesState(msg.arg1, msg.arg2, (String)msg.obj);
mWakeLock.release();
}
};
diff --git a/services/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/java/com/android/server/accessibility/AccessibilityManagerService.java
index 039efbd..3e8f512 100644
--- a/services/java/com/android/server/accessibility/AccessibilityManagerService.java
+++ b/services/java/com/android/server/accessibility/AccessibilityManagerService.java
@@ -104,10 +104,14 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub {
private static final String FUNCTION_REGISTER_UI_TEST_AUTOMATION_SERVICE =
"registerUiTestAutomationService";
+ private static final char COMPONENT_NAME_SEPARATOR = ':';
+
private static final int OWN_PROCESS_ID = android.os.Process.myPid();
private static final int MSG_SHOW_ENABLE_TOUCH_EXPLORATION_DIALOG = 1;
+ private static final int MSG_TOGGLE_TOUCH_EXPLORATION = 2;
+
private static int sIdCounter = 0;
private static int sNextWindowId;
@@ -127,12 +131,14 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub {
private final Set<ComponentName> mEnabledServices = new HashSet<ComponentName>();
+ private final Set<ComponentName> mTouchExplorationGrantedServices = new HashSet<ComponentName>();
+
private final SparseArray<AccessibilityConnectionWrapper> mWindowIdToInteractionConnectionWrapperMap =
new SparseArray<AccessibilityConnectionWrapper>();
private final SparseArray<IBinder> mWindowIdToWindowTokenMap = new SparseArray<IBinder>();
- private final SimpleStringSplitter mStringColonSplitter = new SimpleStringSplitter(':');
+ private final SimpleStringSplitter mStringColonSplitter = new SimpleStringSplitter(COMPONENT_NAME_SEPARATOR);
private final Rect mTempRect = new Rect();
@@ -164,6 +170,8 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub {
private boolean mTouchExplorationGestureStarted;
+ private AlertDialog mEnableTouchExplorationDialog;
+
/**
* Creates a new instance.
*
@@ -208,7 +216,16 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub {
String compPkg = comp.getPackageName();
if (compPkg.equals(packageName)) {
it.remove();
- updateEnabledAccessibilitySerivcesSettingLocked(mEnabledServices);
+ // Update the enabled services setting.
+ persistComponentNamesToSettingLocked(
+ Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES,
+ mEnabledServices);
+ // Update the touch exploration granted services setting.
+ mTouchExplorationGrantedServices.remove(comp);
+ persistComponentNamesToSettingLocked(
+ Settings.Secure.
+ TOUCH_EXPLORATION_GRANTED_ACCESSIBILITY_SERVICES,
+ mEnabledServices);
return;
}
}
@@ -219,7 +236,6 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub {
public boolean onHandleForceStop(Intent intent, String[] packages,
int uid, boolean doit) {
synchronized (mLock) {
- boolean changed = false;
Iterator<ComponentName> it = mEnabledServices.iterator();
while (it.hasNext()) {
ComponentName comp = it.next();
@@ -230,13 +246,12 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub {
return true;
}
it.remove();
- changed = true;
+ persistComponentNamesToSettingLocked(
+ Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES,
+ mEnabledServices);
}
}
}
- if (changed) {
- updateEnabledAccessibilitySerivcesSettingLocked(mEnabledServices);
- }
return false;
}
}
@@ -248,33 +263,19 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub {
// We will update when the automation service dies.
if (mUiAutomationService == null) {
populateAccessibilityServiceListLocked();
+ populateEnabledAccessibilityServicesLocked();
+ populateTouchExplorationGrantedAccessibilityServicesLocked();
handleAccessibilityEnabledSettingChangedLocked();
handleTouchExplorationEnabledSettingChangedLocked();
updateInputFilterLocked();
sendStateToClientsLocked();
}
}
-
return;
}
super.onReceive(context, intent);
}
-
- private void updateEnabledAccessibilitySerivcesSettingLocked(
- Set<ComponentName> enabledServices) {
- Iterator<ComponentName> it = enabledServices.iterator();
- StringBuilder str = new StringBuilder();
- while (it.hasNext()) {
- if (str.length() > 0) {
- str.append(':');
- }
- str.append(it.next().flattenToShortString());
- }
- Settings.Secure.putString(mContext.getContentResolver(),
- Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES,
- str.toString());
- }
};
// package changes
@@ -338,6 +339,25 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub {
synchronized (mLock) {
// We will update when the automation service dies.
if (mUiAutomationService == null) {
+ populateEnabledAccessibilityServicesLocked();
+ manageServicesLocked();
+ }
+ }
+ }
+ });
+
+ Uri touchExplorationGrantedServicesUri = Settings.Secure.getUriFor(
+ Settings.Secure.TOUCH_EXPLORATION_GRANTED_ACCESSIBILITY_SERVICES);
+ contentResolver.registerContentObserver(touchExplorationGrantedServicesUri, false,
+ new ContentObserver(new Handler()) {
+ @Override
+ public void onChange(boolean selfChange) {
+ super.onChange(selfChange);
+ synchronized (mLock) {
+ // We will update when the automation service dies.
+ if (mUiAutomationService == null) {
+ populateTouchExplorationGrantedAccessibilityServicesLocked();
+ unbindAllServicesLocked();
manageServicesLocked();
}
}
@@ -647,6 +667,18 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub {
}
}
+ private void populateEnabledAccessibilityServicesLocked() {
+ populateComponentNamesFromSettingLocked(
+ Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES,
+ mEnabledServices);
+ }
+
+ private void populateTouchExplorationGrantedAccessibilityServicesLocked() {
+ populateComponentNamesFromSettingLocked(
+ Settings.Secure.TOUCH_EXPLORATION_GRANTED_ACCESSIBILITY_SERVICES,
+ mTouchExplorationGrantedServices);
+ }
+
/**
* Performs {@link AccessibilityService}s delayed notification. The delay is configurable
* and denotes the period after the last event before notifying the service.
@@ -689,7 +721,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub {
mServices.add(service);
mComponentNameToServiceMap.put(service.mComponentName, service);
updateInputFilterLocked();
- tryEnableTouchExploration(service);
+ tryEnableTouchExplorationLocked(service);
} catch (RemoteException e) {
/* do nothing */
}
@@ -710,7 +742,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub {
service.unlinkToOwnDeath();
service.dispose();
updateInputFilterLocked();
- tryDisableTouchExploration(service);
+ tryDisableTouchExplorationLocked(service);
return removed;
}
@@ -762,7 +794,6 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub {
* Manages services by starting enabled ones and stopping disabled ones.
*/
private void manageServicesLocked() {
- populateEnabledServicesLocked(mEnabledServices);
final int enabledInstalledServicesCount = updateServicesStateLocked(mInstalledServices,
mEnabledServices);
// No enabled installed services => disable accessibility to avoid
@@ -789,20 +820,21 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub {
}
/**
- * Populates a list with the {@link ComponentName}s of all enabled
- * {@link AccessibilityService}s.
+ * Populates a set with the {@link ComponentName}s stored in a colon
+ * separated value setting.
*
- * @param enabledServices The list.
+ * @param settingName The setting to parse.
+ * @param outComponentNames The output component names.
*/
- private void populateEnabledServicesLocked(Set<ComponentName> enabledServices) {
- enabledServices.clear();
+ private void populateComponentNamesFromSettingLocked(String settingName,
+ Set<ComponentName> outComponentNames) {
+ outComponentNames.clear();
- String servicesValue = Settings.Secure.getString(mContext.getContentResolver(),
- Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES);
+ String settingValue = Settings.Secure.getString(mContext.getContentResolver(), settingName);
- if (servicesValue != null) {
+ if (settingValue != null) {
TextUtils.SimpleStringSplitter splitter = mStringColonSplitter;
- splitter.setString(servicesValue);
+ splitter.setString(settingValue);
while (splitter.hasNext()) {
String str = splitter.next();
if (str == null || str.length() <= 0) {
@@ -810,13 +842,32 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub {
}
ComponentName enabledService = ComponentName.unflattenFromString(str);
if (enabledService != null) {
- enabledServices.add(enabledService);
+ outComponentNames.add(enabledService);
}
}
}
}
/**
+ * Persists the component names in the specified setting in a
+ * colon separated fashion.
+ *
+ * @param settingName The setting name.
+ * @param componentNames The component names.
+ */
+ private void persistComponentNamesToSettingLocked(String settingName,
+ Set<ComponentName> componentNames) {
+ StringBuilder builder = new StringBuilder();
+ for (ComponentName componentName : componentNames) {
+ if (builder.length() > 0) {
+ builder.append(COMPONENT_NAME_SEPARATOR);
+ }
+ builder.append(componentName.flattenToShortString());
+ }
+ Settings.Secure.putString(mContext.getContentResolver(), settingName, builder.toString());
+ }
+
+ /**
* Updates the state of each service by starting (or keeping running) enabled ones and
* stopping the rest.
*
@@ -935,20 +986,21 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub {
Settings.Secure.TOUCH_EXPLORATION_ENABLED, 0) == 1;
}
- private void tryEnableTouchExploration(final Service service) {
+ private void tryEnableTouchExplorationLocked(final Service service) {
if (!mIsTouchExplorationEnabled && service.mRequestTouchExplorationMode) {
- if (!service.mIsAutomation) {
+ final boolean canToggleTouchExploration = mTouchExplorationGrantedServices.contains(
+ service.mComponentName);
+ if (!service.mIsAutomation && !canToggleTouchExploration) {
mMainHandler.obtainMessage(MSG_SHOW_ENABLE_TOUCH_EXPLORATION_DIALOG,
service).sendToTarget();
} else {
- Settings.Secure.putInt(mContext.getContentResolver(),
- Settings.Secure.TOUCH_EXPLORATION_ENABLED, 1);
+ mMainHandler.obtainMessage(MSG_TOGGLE_TOUCH_EXPLORATION, 1, 0).sendToTarget();
}
}
}
- private void tryDisableTouchExploration(Service service) {
- if (mIsTouchExplorationEnabled && service.mReqeustTouchExplorationMode) {
+ private void tryDisableTouchExplorationLocked(Service service) {
+ if (mIsTouchExplorationEnabled) {
synchronized (mLock) {
final int serviceCount = mServices.size();
for (int i = 0; i < serviceCount; i++) {
@@ -957,8 +1009,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub {
return;
}
}
- Settings.Secure.putInt(mContext.getContentResolver(),
- Settings.Secure.TOUCH_EXPLORATION_ENABLED, 0);
+ mMainHandler.obtainMessage(MSG_TOGGLE_TOUCH_EXPLORATION, 0, 0).sendToTarget();
}
}
}
@@ -995,32 +1046,54 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub {
public void handleMessage(Message msg) {
final int type = msg.what;
switch (type) {
+ case MSG_TOGGLE_TOUCH_EXPLORATION: {
+ final int value = msg.arg1;
+ Settings.Secure.putInt(mContext.getContentResolver(),
+ Settings.Secure.TOUCH_EXPLORATION_ENABLED, value);
+ } break;
case MSG_SHOW_ENABLE_TOUCH_EXPLORATION_DIALOG: {
- Service service = (Service) msg.obj;
+ final Service service = (Service) msg.obj;
String label = service.mResolveInfo.loadLabel(
mContext.getPackageManager()).toString();
- final AlertDialog dialog = new AlertDialog.Builder(mContext)
- .setIcon(android.R.drawable.ic_dialog_alert)
- .setPositiveButton(android.R.string.ok, new OnClickListener() {
- @Override
- public void onClick(DialogInterface dialog, int which) {
- Settings.Secure.putInt(mContext.getContentResolver(),
- Settings.Secure.TOUCH_EXPLORATION_ENABLED, 1);
- }
- })
- .setNegativeButton(android.R.string.cancel, new OnClickListener() {
- @Override
- public void onClick(DialogInterface dialog, int which) {
- dialog.dismiss();
- }
- })
- .setTitle(R.string.enable_explore_by_touch_warning_title)
- .setMessage(mContext.getString(
- R.string.enable_explore_by_touch_warning_message, label))
- .create();
- dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_INPUT_METHOD_DIALOG);
- dialog.setCanceledOnTouchOutside(true);
- dialog.show();
+ synchronized (mLock) {
+ if (mIsTouchExplorationEnabled) {
+ return;
+ }
+ if (mEnableTouchExplorationDialog != null
+ && mEnableTouchExplorationDialog.isShowing()) {
+ return;
+ }
+ mEnableTouchExplorationDialog = new AlertDialog.Builder(mContext)
+ .setIcon(android.R.drawable.ic_dialog_alert)
+ .setPositiveButton(android.R.string.ok, new OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ // The user allowed the service to toggle touch exploration.
+ mTouchExplorationGrantedServices.add(service.mComponentName);
+ persistComponentNamesToSettingLocked(
+ Settings.Secure.
+ TOUCH_EXPLORATION_GRANTED_ACCESSIBILITY_SERVICES,
+ mTouchExplorationGrantedServices);
+ // Enable touch exploration.
+ Settings.Secure.putInt(mContext.getContentResolver(),
+ Settings.Secure.TOUCH_EXPLORATION_ENABLED, 1);
+ }
+ })
+ .setNegativeButton(android.R.string.cancel, new OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ dialog.dismiss();
+ }
+ })
+ .setTitle(R.string.enable_explore_by_touch_warning_title)
+ .setMessage(mContext.getString(
+ R.string.enable_explore_by_touch_warning_message, label))
+ .create();
+ mEnableTouchExplorationDialog.getWindow().setType(
+ WindowManager.LayoutParams.TYPE_INPUT_METHOD_DIALOG);
+ mEnableTouchExplorationDialog.setCanceledOnTouchOutside(true);
+ mEnableTouchExplorationDialog.show();
+ }
}
}
}
@@ -1143,8 +1216,16 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub {
mRequestTouchExplorationMode = (info.flags
& AccessibilityServiceInfo.FLAG_REQUEST_TOUCH_EXPLORATION_MODE) != 0;
+ // If this service is up and running we may have to enable touch
+ // exploration, otherwise this will happen when the service connects.
synchronized (mLock) {
- tryAddServiceLocked(this);
+ if (isConfigured()) {
+ if (mRequestTouchExplorationMode) {
+ tryEnableTouchExplorationLocked(this);
+ } else {
+ tryDisableTouchExplorationLocked(this);
+ }
+ }
}
}
@@ -1496,6 +1577,9 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub {
if (mIsAutomation) {
mUiAutomationService = null;
+ populateEnabledAccessibilityServicesLocked();
+ populateTouchExplorationGrantedAccessibilityServicesLocked();
+
handleAccessibilityEnabledSettingChangedLocked();
sendStateToClientsLocked();
diff --git a/services/java/com/android/server/accessibility/TouchExplorer.java b/services/java/com/android/server/accessibility/TouchExplorer.java
index b0b2b8d..4c38ab9 100644
--- a/services/java/com/android/server/accessibility/TouchExplorer.java
+++ b/services/java/com/android/server/accessibility/TouchExplorer.java
@@ -1532,7 +1532,7 @@ public class TouchExplorer {
*/
public ReceivedPointerTracker(Context context) {
mThresholdActivePointer =
- ViewConfiguration.get(context).getScaledTouchSlop() * COEFFICIENT_ACTIVE_POINTER;
+ ViewConfiguration.get(context).getScaledTouchSlop() * COEFFICIENT_ACTIVE_POINTER;//Heie govna
}
/**
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index 6464d7f..9d9b5b8 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -62,6 +62,7 @@ import android.content.ContentProvider;
import android.content.ContentResolver;
import android.content.Context;
import android.content.DialogInterface;
+import android.content.IContentProvider;
import android.content.IIntentReceiver;
import android.content.IIntentSender;
import android.content.Intent;
@@ -1810,12 +1811,11 @@ public final class ActivityManagerService extends ActivityManagerNative
}
}
}
- if (app.conProviders.size() > 0) {
- for (ContentProviderRecord cpr : app.conProviders.keySet()) {
- if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq) {
- updateLruProcessInternalLocked(cpr.proc, oomAdj,
- updateActivityTime, i+1);
- }
+ for (int j=app.conProviders.size()-1; j>=0; j--) {
+ ContentProviderRecord cpr = app.conProviders.get(j).provider;
+ if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq) {
+ updateLruProcessInternalLocked(cpr.proc, oomAdj,
+ updateActivityTime, i+1);
}
}
@@ -3742,7 +3742,7 @@ public final class ActivityManagerService extends ActivityManagerNative
N = providers.size();
for (i=0; i<N; i++) {
- removeDyingProviderLocked(null, providers.get(i));
+ removeDyingProviderLocked(null, providers.get(i), true);
}
if (doit) {
@@ -6058,53 +6058,72 @@ public final class ActivityManagerService extends ActivityManagerNative
return msg;
}
- boolean incProviderCount(ProcessRecord r, final ContentProviderRecord cpr,
- IBinder externalProcessToken) {
+ ContentProviderConnection incProviderCountLocked(ProcessRecord r,
+ final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
if (r != null) {
- Integer cnt = r.conProviders.get(cpr);
- if (DEBUG_PROVIDER) Slog.v(TAG,
- "Adding provider requested by "
- + r.processName + " from process "
- + cpr.info.processName + ": " + cpr.name.flattenToShortString()
- + " cnt=" + (cnt == null ? 1 : cnt));
- if (cnt == null) {
- cpr.clients.add(r);
- r.conProviders.put(cpr, new Integer(1));
- return true;
+ for (int i=0; i<r.conProviders.size(); i++) {
+ ContentProviderConnection conn = r.conProviders.get(i);
+ if (conn.provider == cpr) {
+ if (DEBUG_PROVIDER) Slog.v(TAG,
+ "Adding provider requested by "
+ + r.processName + " from process "
+ + cpr.info.processName + ": " + cpr.name.flattenToShortString()
+ + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
+ if (stable) {
+ conn.stableCount++;
+ conn.numStableIncs++;
+ } else {
+ conn.unstableCount++;
+ conn.numUnstableIncs++;
+ }
+ return conn;
+ }
+ }
+ ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
+ if (stable) {
+ conn.stableCount = 1;
+ conn.numStableIncs = 1;
} else {
- r.conProviders.put(cpr, new Integer(cnt.intValue()+1));
+ conn.unstableCount = 1;
+ conn.numUnstableIncs = 1;
}
- } else {
- cpr.addExternalProcessHandleLocked(externalProcessToken);
+ cpr.connections.add(conn);
+ r.conProviders.add(conn);
+ return conn;
}
- return false;
+ cpr.addExternalProcessHandleLocked(externalProcessToken);
+ return null;
}
- boolean decProviderCount(ProcessRecord r, final ContentProviderRecord cpr,
- IBinder externalProcessToken) {
- if (r != null) {
- Integer cnt = r.conProviders.get(cpr);
+ boolean decProviderCountLocked(ContentProviderConnection conn,
+ ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
+ if (conn != null) {
+ cpr = conn.provider;
if (DEBUG_PROVIDER) Slog.v(TAG,
"Removing provider requested by "
- + r.processName + " from process "
+ + conn.client.processName + " from process "
+ cpr.info.processName + ": " + cpr.name.flattenToShortString()
- + " cnt=" + cnt);
- if (cnt == null || cnt.intValue() <= 1) {
- cpr.clients.remove(r);
- r.conProviders.remove(cpr);
- return true;
+ + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
+ if (stable) {
+ conn.stableCount--;
} else {
- r.conProviders.put(cpr, new Integer(cnt.intValue()-1));
+ conn.unstableCount--;
}
- } else {
- cpr.removeExternalProcessHandleLocked(externalProcessToken);
+ if (conn.stableCount == 0 && conn.unstableCount == 0) {
+ cpr.connections.remove(conn);
+ conn.client.conProviders.remove(conn);
+ return true;
+ }
+ return false;
}
+ cpr.removeExternalProcessHandleLocked(externalProcessToken);
return false;
}
private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
- String name, IBinder token) {
+ String name, IBinder token, boolean stable) {
ContentProviderRecord cpr;
+ ContentProviderConnection conn = null;
ProviderInfo cpi = null;
synchronized(this) {
@@ -6135,20 +6154,19 @@ public final class ActivityManagerService extends ActivityManagerNative
// of being published... but it is also allowed to run
// in the caller's process, so don't make a connection
// and just let the caller instantiate its own instance.
- if (cpr.provider != null) {
- // don't give caller the provider object, it needs
- // to make its own.
- cpr = new ContentProviderRecord(cpr);
- }
- return cpr;
+ ContentProviderHolder holder = cpr.newHolder(null);
+ // don't give caller the provider object, it needs
+ // to make its own.
+ holder.provider = null;
+ return holder;
}
final long origId = Binder.clearCallingIdentity();
// In this case the provider instance already exists, so we can
// return it right away.
- final boolean countChanged = incProviderCount(r, cpr, token);
- if (countChanged) {
+ conn = incProviderCountLocked(r, cpr, token, stable);
+ if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
// If this is a perceptible app accessing the provider,
// make sure to count it as being accessed and thus
@@ -6181,7 +6199,7 @@ public final class ActivityManagerService extends ActivityManagerNative
Slog.i(TAG,
"Existing provider " + cpr.name.flattenToShortString()
+ " is crashing; detaching " + r);
- boolean lastRef = decProviderCount(r, cpr, token);
+ boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread);
if (!lastRef) {
// This wasn't the last ref our process had on
@@ -6189,6 +6207,7 @@ public final class ActivityManagerService extends ActivityManagerNative
return null;
}
providerRunning = false;
+ conn = null;
}
}
@@ -6251,7 +6270,7 @@ public final class ActivityManagerService extends ActivityManagerNative
// info and allow the caller to instantiate it. Only do
// this if the provider is the same user as the caller's
// process, or can run as root (so can be in any process).
- return cpr;
+ return cpr.newHolder(null);
}
if (DEBUG_PROVIDER) {
@@ -6312,7 +6331,10 @@ public final class ActivityManagerService extends ActivityManagerNative
}
mProviderMap.putProviderByName(name, cpr);
- incProviderCount(r, cpr, token);
+ conn = incProviderCountLocked(r, cpr, token, stable);
+ if (conn != null) {
+ conn.waiting = true;
+ }
}
}
@@ -6334,16 +6356,23 @@ public final class ActivityManagerService extends ActivityManagerNative
Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
+ cpr.launchingApp);
}
+ if (conn != null) {
+ conn.waiting = true;
+ }
cpr.wait();
} catch (InterruptedException ex) {
+ } finally {
+ if (conn != null) {
+ conn.waiting = false;
+ }
}
}
}
- return cpr;
+ return cpr != null ? cpr.newHolder(conn) : null;
}
public final ContentProviderHolder getContentProvider(
- IApplicationThread caller, String name) {
+ IApplicationThread caller, String name, boolean stable) {
enforceNotIsolatedCaller("getContentProvider");
if (caller == null) {
String msg = "null IApplicationThread when getting content provider "
@@ -6352,7 +6381,7 @@ public final class ActivityManagerService extends ActivityManagerNative
throw new SecurityException(msg);
}
- return getContentProviderImpl(caller, name, null);
+ return getContentProviderImpl(caller, name, null, stable);
}
public ContentProviderHolder getContentProviderExternal(String name, IBinder token) {
@@ -6362,45 +6391,30 @@ public final class ActivityManagerService extends ActivityManagerNative
}
private ContentProviderHolder getContentProviderExternalUnchecked(String name,IBinder token) {
- return getContentProviderImpl(null, name, token);
+ return getContentProviderImpl(null, name, token, true);
}
/**
* Drop a content provider from a ProcessRecord's bookkeeping
* @param cpr
*/
- public void removeContentProvider(IApplicationThread caller, String name) {
+ public void removeContentProvider(IBinder connection, boolean stable) {
enforceNotIsolatedCaller("removeContentProvider");
synchronized (this) {
- int userId = UserId.getUserId(Binder.getCallingUid());
- ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
- if(cpr == null) {
- // remove from mProvidersByClass
- if (DEBUG_PROVIDER) Slog.v(TAG, name +
- " provider not found in providers list");
- return;
+ ContentProviderConnection conn;
+ try {
+ conn = (ContentProviderConnection)connection;
+ } catch (ClassCastException e) {
+ String msg ="removeContentProvider: " + connection
+ + " not a ContentProviderConnection";
+ Slog.w(TAG, msg);
+ throw new IllegalArgumentException(msg);
}
- final ProcessRecord r = getRecordForAppLocked(caller);
- if (r == null) {
- throw new SecurityException(
- "Unable to find app for caller " + caller +
- " when removing content provider " + name);
+ if (conn == null) {
+ throw new NullPointerException("connection is null");
}
- //update content provider record entry info
- ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
- ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
- if (DEBUG_PROVIDER) Slog.v(TAG, "Removing provider requested by "
- + r.info.processName + " from process "
- + localCpr.appInfo.processName);
- if (localCpr.launchingApp == r) {
- //should not happen. taken care of as a local provider
- Slog.w(TAG, "removeContentProvider called on local provider: "
- + cpr.info.name + " in process " + r.processName);
- return;
- } else {
- if (decProviderCount(r, localCpr, null)) {
- updateOomAdjLocked();
- }
+ if (decProviderCountLocked(conn, null, null, stable)) {
+ updateOomAdjLocked();
}
}
}
@@ -6447,7 +6461,7 @@ public final class ActivityManagerService extends ActivityManagerNative
}
enforceNotIsolatedCaller("publishContentProviders");
- synchronized(this) {
+ synchronized (this) {
final ProcessRecord r = getRecordForAppLocked(caller);
if (DEBUG_MU)
Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
@@ -6499,6 +6513,103 @@ public final class ActivityManagerService extends ActivityManagerNative
}
}
+ public boolean refContentProvider(IBinder connection, int stable, int unstable) {
+ ContentProviderConnection conn;
+ try {
+ conn = (ContentProviderConnection)connection;
+ } catch (ClassCastException e) {
+ String msg ="refContentProvider: " + connection
+ + " not a ContentProviderConnection";
+ Slog.w(TAG, msg);
+ throw new IllegalArgumentException(msg);
+ }
+ if (conn == null) {
+ throw new NullPointerException("connection is null");
+ }
+
+ synchronized (this) {
+ if (stable > 0) {
+ conn.numStableIncs += stable;
+ }
+ stable = conn.stableCount + stable;
+ if (stable < 0) {
+ throw new IllegalStateException("stableCount < 0: " + stable);
+ }
+
+ if (unstable > 0) {
+ conn.numUnstableIncs += unstable;
+ }
+ unstable = conn.unstableCount + unstable;
+ if (unstable < 0) {
+ throw new IllegalStateException("unstableCount < 0: " + unstable);
+ }
+
+ if ((stable+unstable) <= 0) {
+ throw new IllegalStateException("ref counts can't go to zero here: stable="
+ + stable + " unstable=" + unstable);
+ }
+ conn.stableCount = stable;
+ conn.unstableCount = unstable;
+ return !conn.dead;
+ }
+ }
+
+ public void unstableProviderDied(IBinder connection) {
+ ContentProviderConnection conn;
+ try {
+ conn = (ContentProviderConnection)connection;
+ } catch (ClassCastException e) {
+ String msg ="refContentProvider: " + connection
+ + " not a ContentProviderConnection";
+ Slog.w(TAG, msg);
+ throw new IllegalArgumentException(msg);
+ }
+ if (conn == null) {
+ throw new NullPointerException("connection is null");
+ }
+
+ // Safely retrieve the content provider associated with the connection.
+ IContentProvider provider;
+ synchronized (this) {
+ provider = conn.provider.provider;
+ }
+
+ if (provider == null) {
+ // Um, yeah, we're way ahead of you.
+ return;
+ }
+
+ // Make sure the caller is being honest with us.
+ if (provider.asBinder().pingBinder()) {
+ // Er, no, still looks good to us.
+ synchronized (this) {
+ Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
+ + " says " + conn + " died, but we don't agree");
+ return;
+ }
+ }
+
+ // Well look at that! It's dead!
+ synchronized (this) {
+ if (conn.provider.provider != provider) {
+ // But something changed... good enough.
+ return;
+ }
+
+ ProcessRecord proc = conn.provider.proc;
+ if (proc == null || proc.thread == null) {
+ // Seems like the process is already cleaned up.
+ return;
+ }
+
+ // As far as we're concerned, this is just like receiving a
+ // death notification... just a bit prematurely.
+ Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
+ + ") early provider death");
+ appDiedLocked(proc, proc.pid, proc.thread);
+ }
+ }
+
public static final void installSystemProviders() {
List<ProviderInfo> providers;
synchronized (mSelf) {
@@ -10515,36 +10626,62 @@ public final class ActivityManagerService extends ActivityManagerNative
app.executingServices.clear();
}
- private final void removeDyingProviderLocked(ProcessRecord proc,
- ContentProviderRecord cpr) {
- synchronized (cpr) {
- cpr.launchingApp = null;
- cpr.notifyAll();
- }
-
- mProviderMap.removeProviderByClass(cpr.name, UserId.getUserId(cpr.uid));
- String names[] = cpr.info.authority.split(";");
- for (int j = 0; j < names.length; j++) {
- mProviderMap.removeProviderByName(names[j], UserId.getUserId(cpr.uid));
+ private final boolean removeDyingProviderLocked(ProcessRecord proc,
+ ContentProviderRecord cpr, boolean always) {
+ final boolean inLaunching = mLaunchingProviders.contains(cpr);
+
+ if (!inLaunching || always) {
+ synchronized (cpr) {
+ cpr.launchingApp = null;
+ cpr.notifyAll();
+ }
+ mProviderMap.removeProviderByClass(cpr.name, UserId.getUserId(cpr.uid));
+ String names[] = cpr.info.authority.split(";");
+ for (int j = 0; j < names.length; j++) {
+ mProviderMap.removeProviderByName(names[j], UserId.getUserId(cpr.uid));
+ }
}
-
- Iterator<ProcessRecord> cit = cpr.clients.iterator();
- while (cit.hasNext()) {
- ProcessRecord capp = cit.next();
- if (!capp.persistent && capp.thread != null
- && capp.pid != 0
- && capp.pid != MY_PID) {
- Slog.i(TAG, "Kill " + capp.processName
- + " (pid " + capp.pid + "): provider " + cpr.info.name
- + " in dying process " + (proc != null ? proc.processName : "??"));
- EventLog.writeEvent(EventLogTags.AM_KILL, capp.pid,
- capp.processName, capp.setAdj, "dying provider "
- + cpr.name.toShortString());
- Process.killProcessQuiet(capp.pid);
+
+ for (int i=0; i<cpr.connections.size(); i++) {
+ ContentProviderConnection conn = cpr.connections.get(i);
+ if (conn.waiting) {
+ // If this connection is waiting for the provider, then we don't
+ // need to mess with its process unless we are always removing
+ // or for some reason the provider is not currently launching.
+ if (inLaunching && !always) {
+ continue;
+ }
+ }
+ ProcessRecord capp = conn.client;
+ conn.dead = true;
+ if (conn.stableCount > 0) {
+ if (!capp.persistent && capp.thread != null
+ && capp.pid != 0
+ && capp.pid != MY_PID) {
+ Slog.i(TAG, "Kill " + capp.processName
+ + " (pid " + capp.pid + "): provider " + cpr.info.name
+ + " in dying process " + (proc != null ? proc.processName : "??"));
+ EventLog.writeEvent(EventLogTags.AM_KILL, capp.pid,
+ capp.processName, capp.setAdj, "dying provider "
+ + cpr.name.toShortString());
+ Process.killProcessQuiet(capp.pid);
+ }
+ } else if (capp.thread != null && conn.provider.provider != null) {
+ try {
+ capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
+ } catch (RemoteException e) {
+ }
+ // In the protocol here, we don't expect the client to correctly
+ // clean up this connection, we'll just remove it.
+ cpr.connections.remove(i);
+ conn.client.conProviders.remove(conn);
}
}
-
- mLaunchingProviders.remove(cpr);
+
+ if (inLaunching && always) {
+ mLaunchingProviders.remove(cpr);
+ }
+ return inLaunching;
}
/**
@@ -10590,34 +10727,21 @@ public final class ActivityManagerService extends ActivityManagerNative
boolean restart = false;
- int NL = mLaunchingProviders.size();
-
// Remove published content providers.
if (!app.pubProviders.isEmpty()) {
Iterator<ContentProviderRecord> it = app.pubProviders.values().iterator();
while (it.hasNext()) {
ContentProviderRecord cpr = it.next();
- cpr.provider = null;
- cpr.proc = null;
- // See if someone is waiting for this provider... in which
- // case we don't remove it, but just let it restart.
- int i = 0;
- if (!app.bad && allowRestart) {
- for (; i<NL; i++) {
- if (mLaunchingProviders.get(i) == cpr) {
- restart = true;
- break;
- }
- }
- } else {
- i = NL;
+ final boolean always = app.bad || !allowRestart;
+ if (removeDyingProviderLocked(app, cpr, always) || always) {
+ // We left the provider in the launching list, need to
+ // restart it.
+ restart = true;
}
- if (i >= NL) {
- removeDyingProviderLocked(app, cpr);
- NL = mLaunchingProviders.size();
- }
+ cpr.provider = null;
+ cpr.proc = null;
}
app.pubProviders.clear();
}
@@ -10629,10 +10753,9 @@ public final class ActivityManagerService extends ActivityManagerNative
// Unregister from connected content providers.
if (!app.conProviders.isEmpty()) {
- Iterator it = app.conProviders.keySet().iterator();
- while (it.hasNext()) {
- ContentProviderRecord cpr = (ContentProviderRecord)it.next();
- cpr.clients.remove(app);
+ for (int i=0; i<app.conProviders.size(); i++) {
+ ContentProviderConnection conn = app.conProviders.get(i);
+ conn.provider.connections.remove(conn);
}
app.conProviders.clear();
}
@@ -10643,10 +10766,10 @@ public final class ActivityManagerService extends ActivityManagerNative
// XXX Commented out for now. Trying to figure out a way to reproduce
// the actual situation to identify what is actually going on.
if (false) {
- for (int i=0; i<NL; i++) {
+ for (int i=0; i<mLaunchingProviders.size(); i++) {
ContentProviderRecord cpr = (ContentProviderRecord)
mLaunchingProviders.get(i);
- if (cpr.clients.size() <= 0 && !cpr.hasExternalProcessHandles()) {
+ if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
synchronized (cpr) {
cpr.launchingApp = null;
cpr.notifyAll();
@@ -10743,7 +10866,7 @@ public final class ActivityManagerService extends ActivityManagerNative
if (!alwaysBad && !app.bad) {
restart = true;
} else {
- removeDyingProviderLocked(app, cpr);
+ removeDyingProviderLocked(app, cpr, true);
NL = mLaunchingProviders.size();
}
}
@@ -13948,48 +14071,49 @@ public final class ActivityManagerService extends ActivityManagerNative
while (jt.hasNext() && (adj > ProcessList.FOREGROUND_APP_ADJ
|| schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
ContentProviderRecord cpr = jt.next();
- if (cpr.clients.size() != 0) {
- Iterator<ProcessRecord> kt = cpr.clients.iterator();
- while (kt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) {
- ProcessRecord client = kt.next();
- if (client == app) {
- // Being our own client is not interesting.
- continue;
+ for (int i = cpr.connections.size()-1;
+ i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
+ || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE);
+ i--) {
+ ContentProviderConnection conn = cpr.connections.get(i);
+ ProcessRecord client = conn.client;
+ if (client == app) {
+ // Being our own client is not interesting.
+ continue;
+ }
+ int myHiddenAdj = hiddenAdj;
+ if (myHiddenAdj > client.hiddenAdj) {
+ if (client.hiddenAdj > ProcessList.FOREGROUND_APP_ADJ) {
+ myHiddenAdj = client.hiddenAdj;
+ } else {
+ myHiddenAdj = ProcessList.FOREGROUND_APP_ADJ;
}
- int myHiddenAdj = hiddenAdj;
- if (myHiddenAdj > client.hiddenAdj) {
- if (client.hiddenAdj > ProcessList.FOREGROUND_APP_ADJ) {
- myHiddenAdj = client.hiddenAdj;
- } else {
- myHiddenAdj = ProcessList.FOREGROUND_APP_ADJ;
- }
+ }
+ int clientAdj = computeOomAdjLocked(
+ client, myHiddenAdj, TOP_APP, true, doingAll);
+ if (adj > clientAdj) {
+ if (app.hasShownUi && app != mHomeProcess
+ && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
+ app.adjType = "bg-ui-provider";
+ } else {
+ adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
+ ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
+ app.adjType = "provider";
}
- int clientAdj = computeOomAdjLocked(
- client, myHiddenAdj, TOP_APP, true, doingAll);
- if (adj > clientAdj) {
- if (app.hasShownUi && app != mHomeProcess
- && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
- app.adjType = "bg-ui-provider";
- } else {
- adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
- ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
- app.adjType = "provider";
- }
- if (!client.hidden) {
- app.hidden = false;
- }
- if (client.keeping) {
- app.keeping = true;
- }
- app.adjTypeCode = ActivityManager.RunningAppProcessInfo
- .REASON_PROVIDER_IN_USE;
- app.adjSource = client;
- app.adjSourceOom = clientAdj;
- app.adjTarget = cpr.name;
+ if (!client.hidden) {
+ app.hidden = false;
}
- if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
- schedGroup = Process.THREAD_GROUP_DEFAULT;
+ if (client.keeping) {
+ app.keeping = true;
}
+ app.adjTypeCode = ActivityManager.RunningAppProcessInfo
+ .REASON_PROVIDER_IN_USE;
+ app.adjSource = client;
+ app.adjSourceOom = clientAdj;
+ app.adjTarget = cpr.name;
+ }
+ if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
+ schedGroup = Process.THREAD_GROUP_DEFAULT;
}
}
// If the provider has external (non-framework) process
diff --git a/services/java/com/android/server/am/ContentProviderConnection.java b/services/java/com/android/server/am/ContentProviderConnection.java
new file mode 100644
index 0000000..7f69b24
--- /dev/null
+++ b/services/java/com/android/server/am/ContentProviderConnection.java
@@ -0,0 +1,94 @@
+/*
+ * 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.server.am;
+
+import android.os.Binder;
+import android.os.SystemClock;
+import android.util.TimeUtils;
+
+/**
+ * Represents a link between a content provider and client.
+ */
+public class ContentProviderConnection extends Binder {
+ public final ContentProviderRecord provider;
+ public final ProcessRecord client;
+ public final long createTime;
+ public int stableCount;
+ public int unstableCount;
+ // The client of this connection is currently waiting for the provider to appear.
+ // Protected by the provider lock.
+ public boolean waiting;
+ // The provider of this connection is now dead.
+ public boolean dead;
+
+ // For debugging.
+ public int numStableIncs;
+ public int numUnstableIncs;
+
+ public ContentProviderConnection(ContentProviderRecord _provider, ProcessRecord _client) {
+ provider = _provider;
+ client = _client;
+ createTime = SystemClock.elapsedRealtime();
+ }
+
+ public String toString() {
+ StringBuilder sb = new StringBuilder(128);
+ sb.append("ContentProviderConnection{");
+ toShortString(sb);
+ sb.append('}');
+ return sb.toString();
+ }
+
+ public String toShortString() {
+ StringBuilder sb = new StringBuilder(128);
+ toShortString(sb);
+ return sb.toString();
+ }
+
+ public String toClientString() {
+ StringBuilder sb = new StringBuilder(128);
+ toClientString(sb);
+ return sb.toString();
+ }
+
+ public void toShortString(StringBuilder sb) {
+ sb.append(provider.toShortString());
+ sb.append("->");
+ toClientString(sb);
+ }
+
+ public void toClientString(StringBuilder sb) {
+ sb.append(client.toShortString());
+ sb.append(" s");
+ sb.append(stableCount);
+ sb.append("/");
+ sb.append(numStableIncs);
+ sb.append(" u");
+ sb.append(unstableCount);
+ sb.append("/");
+ sb.append(numUnstableIncs);
+ if (waiting) {
+ sb.append(" WAITING");
+ }
+ if (dead) {
+ sb.append(" DEAD");
+ }
+ long nowReal = SystemClock.elapsedRealtime();
+ sb.append(" ");
+ TimeUtils.formatDuration(nowReal-createTime, sb);
+ }
+}
diff --git a/services/java/com/android/server/am/ContentProviderRecord.java b/services/java/com/android/server/am/ContentProviderRecord.java
index 608b09a..fb21b06 100644
--- a/services/java/com/android/server/am/ContentProviderRecord.java
+++ b/services/java/com/android/server/am/ContentProviderRecord.java
@@ -18,6 +18,7 @@ package com.android.server.am;
import android.app.IActivityManager.ContentProviderHolder;
import android.content.ComponentName;
+import android.content.IContentProvider;
import android.content.pm.ApplicationInfo;
import android.content.pm.ProviderInfo;
import android.os.IBinder;
@@ -27,28 +28,35 @@ import android.os.RemoteException;
import android.util.Slog;
import java.io.PrintWriter;
+import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
-class ContentProviderRecord extends ContentProviderHolder {
+class ContentProviderRecord {
+ final ActivityManagerService service;
+ public final ProviderInfo info;
+ final int uid;
+ final ApplicationInfo appInfo;
+ final ComponentName name;
+ public IContentProvider provider;
+ public boolean noReleaseNeeded;
// All attached clients
- final HashSet<ProcessRecord> clients = new HashSet<ProcessRecord>();
+ final ArrayList<ContentProviderConnection> connections
+ = new ArrayList<ContentProviderConnection>();
+ //final HashSet<ProcessRecord> clients = new HashSet<ProcessRecord>();
// Handles for non-framework processes supported by this provider
HashMap<IBinder, ExternalProcessHandle> externalProcessTokenToHandle;
// Count for external process for which we have no handles.
int externalProcessNoHandleCount;
- final ActivityManagerService service;
- final int uid;
- final ApplicationInfo appInfo;
- final ComponentName name;
ProcessRecord proc; // if non-null, hosting process.
ProcessRecord launchingApp; // if non-null, waiting for this app to be launched.
String stringName;
+ String shortStringName;
public ContentProviderRecord(ActivityManagerService _service, ProviderInfo _info,
ApplicationInfo ai, ComponentName _name) {
- super(_info);
service = _service;
+ info = _info;
uid = ai.uid;
appInfo = ai;
name = _name;
@@ -56,12 +64,20 @@ class ContentProviderRecord extends ContentProviderHolder {
}
public ContentProviderRecord(ContentProviderRecord cpr) {
- super(cpr.info);
+ service = cpr.service;
+ info = cpr.info;
uid = cpr.uid;
appInfo = cpr.appInfo;
name = cpr.name;
noReleaseNeeded = cpr.noReleaseNeeded;
- service = cpr.service;
+ }
+
+ public ContentProviderHolder newHolder(ContentProviderConnection conn) {
+ ContentProviderHolder holder = new ContentProviderHolder(info);
+ holder.provider = provider;
+ holder.noReleaseNeeded = noReleaseNeeded;
+ holder.connection = conn;
+ return holder;
}
public boolean canRunHere(ProcessRecord app) {
@@ -120,30 +136,51 @@ class ContentProviderRecord extends ContentProviderHolder {
return (externalProcessTokenToHandle != null || externalProcessNoHandleCount > 0);
}
- void dump(PrintWriter pw, String prefix) {
- pw.print(prefix); pw.print("package=");
- pw.print(info.applicationInfo.packageName);
- pw.print(" process="); pw.println(info.processName);
+ void dump(PrintWriter pw, String prefix, boolean full) {
+ if (full) {
+ pw.print(prefix); pw.print("package=");
+ pw.print(info.applicationInfo.packageName);
+ pw.print(" process="); pw.println(info.processName);
+ }
pw.print(prefix); pw.print("proc="); pw.println(proc);
if (launchingApp != null) {
pw.print(prefix); pw.print("launchingApp="); pw.println(launchingApp);
}
- pw.print(prefix); pw.print("uid="); pw.print(uid);
- pw.print(" provider="); pw.println(provider);
- pw.print(prefix); pw.print("name="); pw.println(info.authority);
- if (info.isSyncable || info.multiprocess || info.initOrder != 0) {
- pw.print(prefix); pw.print("isSyncable="); pw.print(info.isSyncable);
- pw.print("multiprocess="); pw.print(info.multiprocess);
- pw.print(" initOrder="); pw.println(info.initOrder);
+ if (full) {
+ pw.print(prefix); pw.print("uid="); pw.print(uid);
+ pw.print(" provider="); pw.println(provider);
}
- if (hasExternalProcessHandles()) {
- pw.print(prefix); pw.print("externals=");
- pw.println(externalProcessTokenToHandle.size());
+ pw.print(prefix); pw.print("authority="); pw.println(info.authority);
+ if (full) {
+ if (info.isSyncable || info.multiprocess || info.initOrder != 0) {
+ pw.print(prefix); pw.print("isSyncable="); pw.print(info.isSyncable);
+ pw.print(" multiprocess="); pw.print(info.multiprocess);
+ pw.print(" initOrder="); pw.println(info.initOrder);
+ }
}
- if (clients.size() > 0) {
- pw.print(prefix); pw.println("Clients:");
- for (ProcessRecord cproc : clients) {
- pw.print(prefix); pw.print(" - "); pw.println(cproc.toShortString());
+ if (full) {
+ if (hasExternalProcessHandles()) {
+ pw.print(prefix); pw.print("externals=");
+ pw.println(externalProcessTokenToHandle.size());
+ }
+ } else {
+ if (connections.size() > 0 || externalProcessNoHandleCount > 0) {
+ pw.print(prefix); pw.print(connections.size());
+ pw.print(" connections, "); pw.print(externalProcessNoHandleCount);
+ pw.println(" external handles");
+ }
+ }
+ if (connections.size() > 0) {
+ if (full) {
+ pw.print(prefix); pw.println("Connections:");
+ }
+ for (int i=0; i<connections.size(); i++) {
+ ContentProviderConnection conn = connections.get(i);
+ pw.print(prefix); pw.print(" -> "); pw.println(conn.toClientString());
+ if (conn.provider != this) {
+ pw.print(prefix); pw.print(" *** WRONG PROVIDER: ");
+ pw.println(conn.provider);
+ }
}
}
}
@@ -162,6 +199,17 @@ class ContentProviderRecord extends ContentProviderHolder {
return stringName = sb.toString();
}
+ public String toShortString() {
+ if (shortStringName != null) {
+ return shortStringName;
+ }
+ StringBuilder sb = new StringBuilder(128);
+ sb.append(Integer.toHexString(System.identityHashCode(this)));
+ sb.append('/');
+ sb.append(name.flattenToShortString());
+ return shortStringName = sb.toString();
+ }
+
// This class represents a handle from an external process to a provider.
private class ExternalProcessHandle implements DeathRecipient {
private static final String LOG_TAG = "ExternalProcessHanldle";
diff --git a/services/java/com/android/server/am/ProcessRecord.java b/services/java/com/android/server/am/ProcessRecord.java
index 4529ecc..8a3ba7f 100644
--- a/services/java/com/android/server/am/ProcessRecord.java
+++ b/services/java/com/android/server/am/ProcessRecord.java
@@ -125,8 +125,8 @@ class ProcessRecord {
final HashMap<String, ContentProviderRecord> pubProviders
= new HashMap<String, ContentProviderRecord>();
// All ContentProviderRecord process is using
- final HashMap<ContentProviderRecord, Integer> conProviders
- = new HashMap<ContentProviderRecord, Integer>();
+ final ArrayList<ContentProviderConnection> conProviders
+ = new ArrayList<ContentProviderConnection>();
boolean persistent; // always keep this application running?
boolean crashing; // are we in the process of crashing?
@@ -257,25 +257,47 @@ class ProcessRecord {
pw.println();
}
if (activities.size() > 0) {
- pw.print(prefix); pw.print("activities="); pw.println(activities);
+ pw.print(prefix); pw.println("Activities:");
+ for (int i=0; i<activities.size(); i++) {
+ pw.print(prefix); pw.print(" - "); pw.println(activities.get(i));
+ }
}
if (services.size() > 0) {
- pw.print(prefix); pw.print("services="); pw.println(services);
+ pw.print(prefix); pw.println("Services:");
+ for (ServiceRecord sr : services) {
+ pw.print(prefix); pw.print(" - "); pw.println(sr);
+ }
}
if (executingServices.size() > 0) {
- pw.print(prefix); pw.print("executingServices="); pw.println(executingServices);
+ pw.print(prefix); pw.println("Executing Services:");
+ for (ServiceRecord sr : executingServices) {
+ pw.print(prefix); pw.print(" - "); pw.println(sr);
+ }
}
if (connections.size() > 0) {
- pw.print(prefix); pw.print("connections="); pw.println(connections);
+ pw.print(prefix); pw.println("Connections:");
+ for (ConnectionRecord cr : connections) {
+ pw.print(prefix); pw.print(" - "); pw.println(cr);
+ }
}
if (pubProviders.size() > 0) {
- pw.print(prefix); pw.print("pubProviders="); pw.println(pubProviders);
+ pw.print(prefix); pw.println("Published Providers:");
+ for (HashMap.Entry<String, ContentProviderRecord> ent : pubProviders.entrySet()) {
+ pw.print(prefix); pw.print(" - "); pw.println(ent.getKey());
+ pw.print(prefix); pw.print(" -> "); pw.println(ent.getValue());
+ }
}
if (conProviders.size() > 0) {
- pw.print(prefix); pw.print("conProviders="); pw.println(conProviders);
+ pw.print(prefix); pw.println("Connected Providers:");
+ for (int i=0; i<conProviders.size(); i++) {
+ pw.print(prefix); pw.print(" - "); pw.println(conProviders.get(i).toShortString());
+ }
}
if (receivers.size() > 0) {
- pw.print(prefix); pw.print("receivers="); pw.println(receivers);
+ pw.print(prefix); pw.println("Receivers:");
+ for (ReceiverList rl : receivers) {
+ pw.print(prefix); pw.print(" - "); pw.println(rl);
+ }
}
}
diff --git a/services/java/com/android/server/am/ProviderMap.java b/services/java/com/android/server/am/ProviderMap.java
index ccc928f..d148ec3 100644
--- a/services/java/com/android/server/am/ProviderMap.java
+++ b/services/java/com/android/server/am/ProviderMap.java
@@ -177,27 +177,9 @@ public class ProviderMap {
while (it.hasNext()) {
Map.Entry<ComponentName, ContentProviderRecord> e = it.next();
ContentProviderRecord r = e.getValue();
- if (dumpAll) {
- pw.print(" * ");
- pw.println(r);
- r.dump(pw, " ");
- } else {
- pw.print(" * ");
- pw.println(r);
- if (r.proc != null) {
- pw.print(" proc=");
- pw.println(r.proc);
- }
- if (r.launchingApp != null) {
- pw.print(" launchingApp=");
- pw.println(r.launchingApp);
- }
- if (r.clients.size() > 0 || r.externalProcessNoHandleCount > 0) {
- pw.print(" "); pw.print(r.clients.size());
- pw.print(" clients, "); pw.print(r.externalProcessNoHandleCount);
- pw.println(" external handles");
- }
- }
+ pw.print(" * ");
+ pw.println(r);
+ r.dump(pw, " ", dumpAll);
}
}
@@ -210,7 +192,7 @@ public class ProviderMap {
pw.print(" ");
pw.print(e.getKey());
pw.print(": ");
- pw.println(r);
+ pw.println(r.toShortString());
}
}
@@ -221,10 +203,10 @@ public class ProviderMap {
pw.println(" ");
pw.println(" Published content providers (by class):");
dumpProvidersByClassLocked(pw, dumpAll, mGlobalByClass);
- pw.println("");
}
if (mProvidersByClassPerUser.size() > 1) {
+ pw.println("");
for (int i = 0; i < mProvidersByClassPerUser.size(); i++) {
HashMap<ComponentName, ContentProviderRecord> map = mProvidersByClassPerUser.valueAt(i);
pw.println(" User " + mProvidersByClassPerUser.keyAt(i) + ":");
@@ -321,7 +303,7 @@ public class ProviderMap {
if (r.proc != null) pw.println(r.proc.pid);
else pw.println("(not running)");
if (dumpAll) {
- r.dump(pw, innerPrefix);
+ r.dump(pw, innerPrefix, true);
}
}
if (r.proc != null && r.proc.thread != null) {
diff --git a/services/java/com/android/server/am/TaskRecord.java b/services/java/com/android/server/am/TaskRecord.java
index 4b4a89d..3a767c2 100644
--- a/services/java/com/android/server/am/TaskRecord.java
+++ b/services/java/com/android/server/am/TaskRecord.java
@@ -19,9 +19,8 @@ package com.android.server.am;
import android.content.ComponentName;
import android.content.Intent;
import android.content.pm.ActivityInfo;
-import android.content.pm.PackageManager;
-import android.graphics.Bitmap;
import android.os.UserId;
+import android.util.Slog;
import java.io.PrintWriter;
@@ -69,6 +68,8 @@ class TaskRecord extends ThumbnailHolder {
_intent.setSourceBounds(null);
}
}
+ if (ActivityManagerService.DEBUG_TASKS) Slog.v(ActivityManagerService.TAG,
+ "Setting Intent of " + this + " to " + _intent);
intent = _intent;
realActivity = _intent != null ? _intent.getComponent() : null;
origActivity = null;
@@ -80,6 +81,8 @@ class TaskRecord extends ThumbnailHolder {
targetIntent.setComponent(targetComponent);
targetIntent.setSelector(null);
targetIntent.setSourceBounds(null);
+ if (ActivityManagerService.DEBUG_TASKS) Slog.v(ActivityManagerService.TAG,
+ "Setting Intent of " + this + " to target " + targetIntent);
intent = targetIntent;
realActivity = targetComponent;
origActivity = _intent.getComponent();
@@ -103,9 +106,10 @@ class TaskRecord extends ThumbnailHolder {
}
void dump(PrintWriter pw, String prefix) {
- if (numActivities != 0 || rootWasReset) {
+ if (numActivities != 0 || rootWasReset || userId != 0) {
pw.print(prefix); pw.print("numActivities="); pw.print(numActivities);
- pw.print(" rootWasReset="); pw.println(rootWasReset);
+ pw.print(" rootWasReset="); pw.print(rootWasReset);
+ pw.print(" userId="); pw.println(userId);
}
if (affinity != null) {
pw.print(prefix); pw.print("affinity="); pw.println(affinity);
diff --git a/services/java/com/android/server/input/InputManagerService.java b/services/java/com/android/server/input/InputManagerService.java
index d85facc..bdd0aa4 100644
--- a/services/java/com/android/server/input/InputManagerService.java
+++ b/services/java/com/android/server/input/InputManagerService.java
@@ -592,7 +592,7 @@ public class InputManagerService extends IInputManager.Stub implements Watchdog.
deviceIdAndGeneration[i * 2] = inputDevice.getId();
deviceIdAndGeneration[i * 2 + 1] = inputDevice.getGeneration();
- if (isFullKeyboard(inputDevice)) {
+ if (!inputDevice.isVirtual() && inputDevice.isFullKeyboard()) {
if (!containsInputDeviceWithDescriptor(oldInputDevices,
inputDevice.getDescriptor())) {
mTempFullKeyboards.add(numFullKeyboardsAdded++, inputDevice);
@@ -695,12 +695,6 @@ public class InputManagerService extends IInputManager.Stub implements Watchdog.
reloadKeyboardLayouts();
}
- private static boolean isFullKeyboard(InputDevice inputDevice) {
- return !inputDevice.isVirtual()
- && (inputDevice.getSources() & InputDevice.SOURCE_KEYBOARD) != 0
- && inputDevice.getKeyboardType() == InputDevice.KEYBOARD_TYPE_ALPHABETIC;
- }
-
private static boolean containsInputDeviceWithDescriptor(InputDevice[] inputDevices,
String descriptor) {
final int numDevices = inputDevices.length;
diff --git a/services/java/com/android/server/location/GeocoderProxy.java b/services/java/com/android/server/location/GeocoderProxy.java
index b38ea13..07f3125 100644
--- a/services/java/com/android/server/location/GeocoderProxy.java
+++ b/services/java/com/android/server/location/GeocoderProxy.java
@@ -39,27 +39,28 @@ public class GeocoderProxy {
private static final String TAG = "GeocoderProxy";
+ public static final String SERVICE_ACTION =
+ "com.android.location.service.GeocodeProvider";
+
private final Context mContext;
private final Intent mIntent;
private final Object mMutex = new Object(); // synchronizes access to mServiceConnection
- private Connection mServiceConnection = new Connection(); // never null
+ private Connection mServiceConnection; // never null after ctor
- public GeocoderProxy(Context context, String serviceName) {
+ public GeocoderProxy(Context context, String packageName) {
mContext = context;
- mIntent = new Intent(serviceName);
- mContext.bindService(mIntent, mServiceConnection,
- Context.BIND_AUTO_CREATE | Context.BIND_NOT_FOREGROUND
- | Context.BIND_ALLOW_OOM_MANAGEMENT);
+ mIntent = new Intent(SERVICE_ACTION);
+ reconnect(packageName);
}
- /**
- * When unbundled NetworkLocationService package is updated, we
- * need to unbind from the old version and re-bind to the new one.
- */
- public void reconnect() {
+ /** Bind to service. Will reconnect if already connected */
+ public void reconnect(String packageName) {
synchronized (mMutex) {
- mContext.unbindService(mServiceConnection);
+ if (mServiceConnection != null) {
+ mContext.unbindService(mServiceConnection);
+ }
mServiceConnection = new Connection();
+ mIntent.setPackage(packageName);
mContext.bindService(mIntent, mServiceConnection,
Context.BIND_AUTO_CREATE | Context.BIND_NOT_FOREGROUND
| Context.BIND_ALLOW_OOM_MANAGEMENT);
diff --git a/services/java/com/android/server/location/LocationProviderProxy.java b/services/java/com/android/server/location/LocationProviderProxy.java
index 0bc1664..a227ab6 100644
--- a/services/java/com/android/server/location/LocationProviderProxy.java
+++ b/services/java/com/android/server/location/LocationProviderProxy.java
@@ -42,12 +42,15 @@ public class LocationProviderProxy implements LocationProviderInterface {
private static final String TAG = "LocationProviderProxy";
+ public static final String SERVICE_ACTION =
+ "com.android.location.service.NetworkLocationProvider";
+
private final Context mContext;
private final String mName;
private final Intent mIntent;
private final Handler mHandler;
private final Object mMutex = new Object(); // synchronizes access to non-final members
- private Connection mServiceConnection = new Connection(); // never null
+ private Connection mServiceConnection; // never null after ctor
// cached values set by the location manager
private boolean mLocationTracking = false;
@@ -58,28 +61,26 @@ public class LocationProviderProxy implements LocationProviderInterface {
private NetworkInfo mNetworkInfo;
// constructor for proxying location providers implemented in a separate service
- public LocationProviderProxy(Context context, String name, String serviceName,
+ public LocationProviderProxy(Context context, String name, String packageName,
Handler handler) {
mContext = context;
mName = name;
- mIntent = new Intent(serviceName);
+ mIntent = new Intent(SERVICE_ACTION);
mHandler = handler;
- mContext.bindService(mIntent, mServiceConnection,
- Context.BIND_AUTO_CREATE | Context.BIND_NOT_FOREGROUND
- | Context.BIND_ALLOW_OOM_MANAGEMENT);
+ reconnect(packageName);
}
- /**
- * When unbundled NetworkLocationService package is updated, we
- * need to unbind from the old version and re-bind to the new one.
- */
- public void reconnect() {
+ /** Bind to service. Will reconnect if already connected */
+ public void reconnect(String packageName) {
synchronized (mMutex) {
- mContext.unbindService(mServiceConnection);
+ if (mServiceConnection != null) {
+ mContext.unbindService(mServiceConnection);
+ }
mServiceConnection = new Connection();
+ mIntent.setPackage(packageName);
mContext.bindService(mIntent, mServiceConnection,
- Context.BIND_AUTO_CREATE | Context.BIND_NOT_FOREGROUND
- | Context.BIND_ALLOW_OOM_MANAGEMENT);
+ Context.BIND_AUTO_CREATE | Context.BIND_NOT_FOREGROUND |
+ Context.BIND_ALLOW_OOM_MANAGEMENT);
}
}
diff --git a/services/java/com/android/server/wm/AppWindowAnimator.java b/services/java/com/android/server/wm/AppWindowAnimator.java
index de756b1..1953ad7 100644
--- a/services/java/com/android/server/wm/AppWindowAnimator.java
+++ b/services/java/com/android/server/wm/AppWindowAnimator.java
@@ -79,12 +79,9 @@ public class AppWindowAnimator {
}
public void setDummyAnimation() {
- if (animation == null) {
- if (WindowManagerService.localLOGV) Slog.v(
- TAG, "Setting dummy animation in " + mAppToken);
- animation = sDummyAnimation;
- animInitialized = false;
- }
+ if (WindowManagerService.localLOGV) Slog.v(TAG, "Setting dummy animation in " + mAppToken);
+ animation = sDummyAnimation;
+ animInitialized = false;
hasTransformation = true;
transformation.clear();
transformation.setAlpha(mAppToken.reportedVisible ? 1 : 0);
diff --git a/services/java/com/android/server/wm/WindowManagerService.java b/services/java/com/android/server/wm/WindowManagerService.java
index b1612a1..10919f2 100755
--- a/services/java/com/android/server/wm/WindowManagerService.java
+++ b/services/java/com/android/server/wm/WindowManagerService.java
@@ -1638,7 +1638,7 @@ public class WindowManagerService extends IWindowManager.Stub
// it is of no interest to us.
if (w.mAppToken.hidden && w.mAppToken.mAppAnimator.animation == null) {
if (DEBUG_WALLPAPER) Slog.v(TAG,
- "Skipping not hidden or animating token: " + w);
+ "Skipping hidden and not animating token: " + w);
continue;
}
}
@@ -3544,7 +3544,8 @@ public class WindowManagerService extends IWindowManager.Stub
wtoken.groupId = groupId;
wtoken.appFullscreen = fullscreen;
wtoken.requestedOrientation = requestedOrientation;
- if (DEBUG_TOKEN_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(TAG, "addAppToken: " + wtoken);
+ if (DEBUG_TOKEN_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(TAG, "addAppToken: " + wtoken
+ + " at " + addPos);
mAppTokens.add(addPos, wtoken);
addAppTokenToAnimating(addPos, wtoken);
mTokenMap.put(token.asBinder(), wtoken);
@@ -3864,6 +3865,7 @@ public class WindowManagerService extends IWindowManager.Stub
if (DEBUG_APP_TRANSITIONS) Slog.v(
TAG, "Prepare app transition: transit=" + transit
+ " mNextAppTransition=" + mNextAppTransition
+ + " alwaysKeepCurrent=" + alwaysKeepCurrent
+ " Callers=" + Debug.getCallers(3));
if (okToDisplay()) {
if (mNextAppTransition == WindowManagerPolicy.TRANSIT_UNSET
@@ -3933,6 +3935,15 @@ public class WindowManagerService extends IWindowManager.Stub
}
}
+ private void cancelWindowAnimations(final AppWindowToken wtoken) {
+ for (int i = wtoken.windows.size() - 1; i >= 0; i--) {
+ final WindowStateAnimator winAnimator = wtoken.windows.get(i).mWinAnimator;
+ if (winAnimator.isAnimating()) {
+ winAnimator.clearAnimation();
+ }
+ }
+ }
+
public void executeAppTransition() {
if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
"executeAppTransition()")) {
@@ -3948,6 +3959,12 @@ public class WindowManagerService extends IWindowManager.Stub
}
if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
mAppTransitionReady = true;
+ for (int i = mOpeningApps.size() - 1; i >= 0; i--) {
+ cancelWindowAnimations(mOpeningApps.get(i));
+ }
+ for (int i = mClosingApps.size() - 1; i >= 0; i--) {
+ cancelWindowAnimations(mClosingApps.get(i));
+ }
final long origId = Binder.clearCallingIdentity();
performLayoutAndPlaceSurfacesLocked();
Binder.restoreCallingIdentity(origId);
@@ -4295,6 +4312,7 @@ public class WindowManagerService extends IWindowManager.Stub
if (DEBUG_APP_TRANSITIONS) Slog.v(
TAG, "Setting dummy animation on: " + wtoken);
+ cancelWindowAnimations(wtoken);
wtoken.mAppAnimator.setDummyAnimation();
mOpeningApps.remove(wtoken);
mClosingApps.remove(wtoken);
@@ -4816,8 +4834,7 @@ public class WindowManagerService extends IWindowManager.Stub
}
}
- if (mNextAppTransition == WindowManagerPolicy.TRANSIT_UNSET
- && !mAppTransitionRunning) {
+ if (!mAppTransitionRunning) {
mAnimatingAppTokens.clear();
mAnimatingAppTokens.addAll(mAppTokens);
moveAppWindowsLocked(tokens, mAppTokens.size());
@@ -4836,8 +4853,7 @@ public class WindowManagerService extends IWindowManager.Stub
final long origId = Binder.clearCallingIdentity();
synchronized(mWindowMap) {
final int N = tokens.size();
- if (N > 0 && mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET
- && !mAppTransitionRunning) {
+ if (N > 0 && !mAppTransitionRunning) {
// animating towards back, hang onto old list for duration of animation.
mAnimatingAppTokens.clear();
mAnimatingAppTokens.addAll(mAppTokens);
@@ -4857,8 +4873,7 @@ public class WindowManagerService extends IWindowManager.Stub
}
}
- if (mNextAppTransition == WindowManagerPolicy.TRANSIT_UNSET
- && !mAppTransitionRunning) {
+ if (!mAppTransitionRunning) {
mAnimatingAppTokens.clear();
mAnimatingAppTokens.addAll(mAppTokens);
moveAppWindowsLocked(tokens, 0);
@@ -5321,7 +5336,8 @@ public class WindowManagerService extends IWindowManager.Stub
// the background..)
if (on) {
boolean isVisible = false;
- for (WindowState ws : mWindows) {
+ for (int i = mWindows.size() - 1; i >= 0; i--) {
+ final WindowState ws = mWindows.get(i);
if (ws.mSession.mPid == pid && ws.isVisibleLw()) {
isVisible = true;
break;
@@ -6439,7 +6455,10 @@ public class WindowManagerService extends IWindowManager.Stub
int keyboardPresence = 0;
int navigationPresence = 0;
- for (InputDevice device : mInputManager.getInputDevices()) {
+ final InputDevice[] devices = mInputManager.getInputDevices();
+ final int len = devices.length;
+ for (int i = 0; i < len; i++) {
+ InputDevice device = devices[i];
if (!device.isVirtual()) {
final int sources = device.getSources();
final int presenceFlag = device.isExternal() ?
@@ -6447,17 +6466,18 @@ public class WindowManagerService extends IWindowManager.Stub
WindowManagerPolicy.PRESENCE_INTERNAL;
if (mIsTouchDevice) {
- if ((sources & InputDevice.SOURCE_TOUCHSCREEN) != 0) {
+ if ((sources & InputDevice.SOURCE_TOUCHSCREEN) ==
+ InputDevice.SOURCE_TOUCHSCREEN) {
config.touchscreen = Configuration.TOUCHSCREEN_FINGER;
}
} else {
config.touchscreen = Configuration.TOUCHSCREEN_NOTOUCH;
}
- if ((sources & InputDevice.SOURCE_TRACKBALL) != 0) {
+ if ((sources & InputDevice.SOURCE_TRACKBALL) == InputDevice.SOURCE_TRACKBALL) {
config.navigation = Configuration.NAVIGATION_TRACKBALL;
navigationPresence |= presenceFlag;
- } else if ((sources & InputDevice.SOURCE_DPAD) != 0
+ } else if ((sources & InputDevice.SOURCE_DPAD) == InputDevice.SOURCE_DPAD
&& config.navigation == Configuration.NAVIGATION_NONAV) {
config.navigation = Configuration.NAVIGATION_DPAD;
navigationPresence |= presenceFlag;
@@ -7948,7 +7968,7 @@ public class WindowManagerService extends IWindowManager.Stub
for (i=0; i<NN && goodToGo; i++) {
AppWindowToken wtoken = mOpeningApps.get(i);
if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
- "Check opening app" + wtoken + ": allDrawn="
+ "Check opening app=" + wtoken + ": allDrawn="
+ wtoken.allDrawn + " startingDisplayed="
+ wtoken.startingDisplayed + " startingMoved="
+ wtoken.startingMoved);
@@ -8058,7 +8078,7 @@ public class WindowManagerService extends IWindowManager.Stub
}
if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
"New transit: " + transit);
- } else if (oldWallpaper != null) {
+ } else if ((oldWallpaper != null) && (oldWallpaper != mWallpaperTarget)) {
// We are transitioning from an activity with
// a wallpaper to one without.
transit = WindowManagerPolicy.TRANSIT_WALLPAPER_CLOSE;
diff --git a/services/sensorservice/SensorService.cpp b/services/sensorservice/SensorService.cpp
index d3b667f..9e5e84b 100644
--- a/services/sensorservice/SensorService.cpp
+++ b/services/sensorservice/SensorService.cpp
@@ -225,9 +225,10 @@ bool SensorService::threadLoop()
{
ALOGD("nuSensorService thread starting...");
- const size_t numEventMax = 16 * (1 + mVirtualSensorList.size());
- sensors_event_t buffer[numEventMax];
- sensors_event_t scratch[numEventMax];
+ const size_t numEventMax = 16;
+ const size_t minBufferSize = numEventMax + numEventMax * mVirtualSensorList.size();
+ sensors_event_t buffer[minBufferSize];
+ sensors_event_t scratch[minBufferSize];
SensorDevice& device(SensorDevice::getInstance());
const size_t vcount = mVirtualSensorList.size();
@@ -255,10 +256,17 @@ bool SensorService::threadLoop()
fusion.process(event[i]);
}
}
- for (size_t i=0 ; i<size_t(count) ; i++) {
+ for (size_t i=0 ; i<size_t(count) && k<minBufferSize ; i++) {
for (size_t j=0 ; j<activeVirtualSensorCount ; j++) {
+ if (count + k >= minBufferSize) {
+ ALOGE("buffer too small to hold all events: "
+ "count=%u, k=%u, size=%u",
+ count, k, minBufferSize);
+ break;
+ }
sensors_event_t out;
- if (virtualSensors.valueAt(j)->process(&out, event[i])) {
+ SensorInterface* si = virtualSensors.valueAt(j);
+ if (si->process(&out, event[i])) {
buffer[count + k] = out;
k++;
}
diff --git a/telephony/java/com/android/internal/telephony/SMSDispatcher.java b/telephony/java/com/android/internal/telephony/SMSDispatcher.java
index 28b729d..41125dd 100644
--- a/telephony/java/com/android/internal/telephony/SMSDispatcher.java
+++ b/telephony/java/com/android/internal/telephony/SMSDispatcher.java
@@ -78,6 +78,10 @@ public abstract class SMSDispatcher extends Handler {
public static final String RECEIVE_EMERGENCY_BROADCAST_PERMISSION =
"android.permission.RECEIVE_EMERGENCY_BROADCAST";
+ /** Permission required to send SMS to short codes without user confirmation. */
+ private static final String SEND_SMS_NO_CONFIRMATION_PERMISSION =
+ "android.permission.SEND_SMS_NO_CONFIRMATION";
+
/** Query projection for checking for duplicate message segments. */
private static final String[] PDU_PROJECTION = new String[] {
"pdu"
@@ -944,7 +948,8 @@ public abstract class SMSDispatcher extends Handler {
* @return true if the destination is approved; false if user confirmation event was sent
*/
boolean checkDestination(SmsTracker tracker) {
- if (mUsageMonitor.isApprovedShortCodeSender(tracker.mAppPackage)) {
+ if (mContext.checkCallingOrSelfPermission(SEND_SMS_NO_CONFIRMATION_PERMISSION)
+ == PackageManager.PERMISSION_GRANTED) {
return true; // app is pre-approved to send to short codes
} else {
String countryIso = mTelephonyManager.getSimCountryIso();
diff --git a/telephony/java/com/android/internal/telephony/SmsUsageMonitor.java b/telephony/java/com/android/internal/telephony/SmsUsageMonitor.java
index f40958d..1804d97 100644
--- a/telephony/java/com/android/internal/telephony/SmsUsageMonitor.java
+++ b/telephony/java/com/android/internal/telephony/SmsUsageMonitor.java
@@ -81,12 +81,6 @@ public class SmsUsageMonitor {
private final HashMap<String, ArrayList<Long>> mSmsStamp =
new HashMap<String, ArrayList<Long>>();
- /**
- * Hash of package names that are allowed to send to short codes.
- * TODO: persist this across reboots.
- */
- private final HashSet<String> mApprovedShortCodeSenders = new HashSet<String>();
-
/** Context for retrieving regexes from XML resource. */
private final Context mContext;
@@ -248,9 +242,6 @@ public class SmsUsageMonitor {
DEFAULT_SMS_CHECK_PERIOD);
mSettingsObserverHandler = new SettingsObserverHandler();
-
- // system MMS app is always allowed to send to short codes
- mApprovedShortCodeSenders.add("com.android.mms");
}
/**
@@ -358,28 +349,6 @@ public class SmsUsageMonitor {
}
/**
- * Return whether the app is approved to send to any short code.
- * @param appName the package name of the app requesting to send an SMS
- * @return true if the app is approved; false if we need to confirm short code destinations
- */
- public boolean isApprovedShortCodeSender(String appName) {
- synchronized (mApprovedShortCodeSenders) {
- return mApprovedShortCodeSenders.contains(appName);
- }
- }
-
- /**
- * Add app package name to the list of approved short code senders.
- * @param appName the package name of the app to add
- */
- public void addApprovedShortCodeSender(String appName) {
- if (DBG) log("Adding " + appName + " to list of approved short code senders.");
- synchronized (mApprovedShortCodeSenders) {
- mApprovedShortCodeSenders.add(appName);
- }
- }
-
- /**
* Check if the destination is a possible premium short code.
* NOTE: the caller is expected to strip non-digits from the destination number with
* {@link PhoneNumberUtils#extractNetworkPortion} before calling this method.
diff --git a/test-runner/src/android/test/mock/MockContentResolver.java b/test-runner/src/android/test/mock/MockContentResolver.java
index 65eb21b..715da0f 100644
--- a/test-runner/src/android/test/mock/MockContentResolver.java
+++ b/test-runner/src/android/test/mock/MockContentResolver.java
@@ -118,6 +118,11 @@ public class MockContentResolver extends ContentResolver {
return releaseProvider(icp);
}
+ /** @hide */
+ @Override
+ public void unstableProviderDied(IContentProvider icp) {
+ }
+
/**
* Overrides {@link android.content.ContentResolver#notifyChange(Uri, ContentObserver, boolean)
* ContentResolver.notifChange(Uri, ContentObserver, boolean)}. All parameters are ignored.
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContentResolver.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContentResolver.java
index fec2c3f..8d259d7 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContentResolver.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContentResolver.java
@@ -72,6 +72,11 @@ public class BridgeContentResolver extends ContentResolver {
return releaseProvider(icp);
}
+ /** @hide */
+ @Override
+ public void unstableProviderDied(IContentProvider icp) {
+ }
+
/**
* Stub for the layoutlib bridge content resolver.
*/
diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pService.java b/wifi/java/android/net/wifi/p2p/WifiP2pService.java
index cc49cae..c800182 100644
--- a/wifi/java/android/net/wifi/p2p/WifiP2pService.java
+++ b/wifi/java/android/net/wifi/p2p/WifiP2pService.java
@@ -425,6 +425,12 @@ public class WifiP2pService extends IWifiP2pManager.Stub {
case WifiMonitor.NETWORK_DISCONNECTION_EVENT:
case WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT:
case WifiMonitor.P2P_GROUP_REMOVED_EVENT:
+ case WifiMonitor.P2P_DEVICE_FOUND_EVENT:
+ case WifiMonitor.P2P_DEVICE_LOST_EVENT:
+ case WifiMonitor.P2P_FIND_STOPPED_EVENT:
+ case WifiMonitor.P2P_SERV_DISC_RESP_EVENT:
+ case WifiStateMachine.CMD_ENABLE_P2P:
+ case WifiStateMachine.CMD_DISABLE_P2P:
case PEER_CONNECTION_USER_ACCEPT:
case PEER_CONNECTION_USER_REJECT:
case GROUP_CREATING_TIMED_OUT:
@@ -837,6 +843,13 @@ public class WifiP2pService extends IWifiP2pManager.Stub {
transitionTo(mUserAuthorizingInvitationState);
}
break;
+ case WifiMonitor.P2P_FIND_STOPPED_EVENT:
+ // When discovery stops in inactive state, flush to clear
+ // state peer data
+ mWifiNative.p2pFlush();
+ mServiceDiscReqId = null;
+ sendP2pDiscoveryChangedBroadcast(false);
+ break;
case WifiMonitor.P2P_PROV_DISC_PBC_REQ_EVENT:
case WifiMonitor.P2P_PROV_DISC_ENTER_PIN_EVENT:
case WifiMonitor.P2P_PROV_DISC_SHOW_PIN_EVENT:
@@ -873,6 +886,7 @@ public class WifiP2pService extends IWifiP2pManager.Stub {
@Override
public boolean processMessage(Message message) {
if (DBG) logd(getName() + message.toString());
+ boolean ret = HANDLED;
switch (message.what) {
case GROUP_CREATING_TIMED_OUT:
if (mGroupCreatingTimeoutIndex == message.arg1) {
@@ -881,6 +895,16 @@ public class WifiP2pService extends IWifiP2pManager.Stub {
transitionTo(mInactiveState);
}
break;
+ case WifiMonitor.P2P_DEVICE_LOST_EVENT:
+ WifiP2pDevice device = (WifiP2pDevice) message.obj;
+ if (!mSavedPeerConfig.deviceAddress.equals(device.deviceAddress)) {
+ // Do the regular device lost handling
+ ret = NOT_HANDLED;
+ break;
+ }
+ // Do nothing
+ if (DBG) logd("Retain connecting device " + device);
+ break;
case WifiP2pManager.DISCOVER_PEERS:
/* Discovery will break negotiation */
replyToMessage(message, WifiP2pManager.DISCOVER_PEERS_FAILED,
@@ -898,9 +922,9 @@ public class WifiP2pService extends IWifiP2pManager.Stub {
replyToMessage(message, WifiP2pManager.CANCEL_CONNECT_SUCCEEDED);
break;
default:
- return NOT_HANDLED;
+ ret = NOT_HANDLED;
}
- return HANDLED;
+ return ret;
}
}