diff options
Diffstat (limited to 'core')
99 files changed, 1918 insertions, 1255 deletions
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/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/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/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/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-am/strings.xml b/core/res/res/values-am/strings.xml index c8bb77e..fb11af3 100644 --- a/core/res/res/values-am/strings.xml +++ b/core/res/res/values-am/strings.xml @@ -855,12 +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> - <!-- 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="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"> @@ -1127,10 +1124,8 @@ <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="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> @@ -1324,6 +1319,5 @@ <string name="launchBrowserDefault" msgid="2057951947297614725">"ማሰሺያን አስነሳ?"</string> <string name="SetupCallDefault" msgid="5834948469253758575">"ጥሪ ተቀበል?"</string> <string name="activity_resolver_use_always" msgid="8017770747801494933">"ዘወትር"</string> - <!-- no translation found for activity_resolver_use_once (2404644797149173758) --> - <skip /> + <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 7798b0a..d70aec8 100644 --- a/core/res/res/values-ar/strings.xml +++ b/core/res/res/values-ar/strings.xml @@ -855,12 +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> - <!-- 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="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"> @@ -1127,10 +1124,8 @@ <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="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> @@ -1324,6 +1319,5 @@ <string name="launchBrowserDefault" msgid="2057951947297614725">"تشغيل المتصفح؟"</string> <string name="SetupCallDefault" msgid="5834948469253758575">"هل تريد قبول المكالمة؟"</string> <string name="activity_resolver_use_always" msgid="8017770747801494933">"دومًا"</string> - <!-- no translation found for activity_resolver_use_once (2404644797149173758) --> - <skip /> + <string name="activity_resolver_use_once" msgid="2404644797149173758">"مرة واحدة فقط"</string> </resources> diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml index 97876f6..4190bdb 100644 --- a/core/res/res/values-ca/strings.xml +++ b/core/res/res/values-ca/strings.xml @@ -855,12 +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> - <!-- 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="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"> @@ -1127,10 +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> - <!-- no translation found for select_keyboard_layout_notification_title (1407367017263030773) --> - <skip /> - <!-- no translation found for select_keyboard_layout_notification_message (4465907700449257063) --> - <skip /> + <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> @@ -1324,6 +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> - <!-- no translation found for activity_resolver_use_once (2404644797149173758) --> - <skip /> + <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 acd4bba..ad25a3e 100644 --- a/core/res/res/values-cs/strings.xml +++ b/core/res/res/values-cs/strings.xml @@ -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> @@ -1205,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> diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml index c44f789..8cde21f 100644 --- a/core/res/res/values-el/strings.xml +++ b/core/res/res/values-el/strings.xml @@ -855,12 +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> - <!-- 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="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"> @@ -1127,10 +1124,8 @@ <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="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> @@ -1324,6 +1319,5 @@ <string name="launchBrowserDefault" msgid="2057951947297614725">"Εκκίνηση προγράμματος περιήγησης;"</string> <string name="SetupCallDefault" msgid="5834948469253758575">"Αποδοχή κλήσης;"</string> <string name="activity_resolver_use_always" msgid="8017770747801494933">"Πάντα"</string> - <!-- no translation found for activity_resolver_use_once (2404644797149173758) --> - <skip /> + <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 a54c479..4ad7daf 100644 --- a/core/res/res/values-en-rGB/strings.xml +++ b/core/res/res/values-en-rGB/strings.xml @@ -855,12 +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> - <!-- 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="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"> @@ -1127,10 +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> - <!-- no translation found for select_keyboard_layout_notification_title (1407367017263030773) --> - <skip /> - <!-- no translation found for select_keyboard_layout_notification_message (4465907700449257063) --> - <skip /> + <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> @@ -1324,6 +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> - <!-- no translation found for activity_resolver_use_once (2404644797149173758) --> - <skip /> + <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 64429e9..4d861fc 100644 --- a/core/res/res/values-es-rUS/strings.xml +++ b/core/res/res/values-es-rUS/strings.xml @@ -855,12 +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> - <!-- 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="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"> @@ -1127,10 +1124,8 @@ <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> - <!-- no translation found for select_keyboard_layout_notification_title (1407367017263030773) --> - <skip /> - <!-- no translation found for select_keyboard_layout_notification_message (4465907700449257063) --> - <skip /> + <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> @@ -1324,6 +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> - <!-- no translation found for activity_resolver_use_once (2404644797149173758) --> - <skip /> + <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 f5ffece..f5d8795 100644 --- a/core/res/res/values-es/strings.xml +++ b/core/res/res/values-es/strings.xml @@ -855,12 +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> - <!-- 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="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"> @@ -1127,10 +1124,8 @@ <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> - <!-- no translation found for select_keyboard_layout_notification_title (1407367017263030773) --> - <skip /> - <!-- no translation found for select_keyboard_layout_notification_message (4465907700449257063) --> - <skip /> + <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> @@ -1324,6 +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> - <!-- no translation found for activity_resolver_use_once (2404644797149173758) --> - <skip /> + <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 ea57cf5..af4b160 100644 --- a/core/res/res/values-et/strings.xml +++ b/core/res/res/values-et/strings.xml @@ -318,7 +318,7 @@ <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ääsuteenuseteenuse ülataseme liidesega. Tavarakenduste puhul ei tohiks seda kunagi vaja minna."</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> @@ -855,12 +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> - <!-- 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="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"> @@ -1127,10 +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> - <!-- no translation found for select_keyboard_layout_notification_title (1407367017263030773) --> - <skip /> - <!-- no translation found for select_keyboard_layout_notification_message (4465907700449257063) --> - <skip /> + <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> @@ -1324,6 +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> - <!-- no translation found for activity_resolver_use_once (2404644797149173758) --> - <skip /> + <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 393ba0c..cb83ba3 100644 --- a/core/res/res/values-fa/strings.xml +++ b/core/res/res/values-fa/strings.xml @@ -855,12 +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> - <!-- 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="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"> @@ -1127,10 +1124,8 @@ <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="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> @@ -1324,6 +1319,5 @@ <string name="launchBrowserDefault" msgid="2057951947297614725">"مرورگر راهاندازی شود؟"</string> <string name="SetupCallDefault" msgid="5834948469253758575">"تماس را میپذیرید؟"</string> <string name="activity_resolver_use_always" msgid="8017770747801494933">"همیشه"</string> - <!-- no translation found for activity_resolver_use_once (2404644797149173758) --> - <skip /> + <string name="activity_resolver_use_once" msgid="2404644797149173758">"فقط یک بار"</string> </resources> diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml index f249c2c..b2879e9 100644 --- a/core/res/res/values-in/strings.xml +++ b/core/res/res/values-in/strings.xml @@ -606,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> @@ -641,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> @@ -662,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> @@ -691,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> @@ -707,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> @@ -855,12 +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> - <!-- 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="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"> @@ -1127,10 +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> - <!-- no translation found for select_keyboard_layout_notification_title (1407367017263030773) --> - <skip /> - <!-- no translation found for select_keyboard_layout_notification_message (4465907700449257063) --> - <skip /> + <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> @@ -1324,6 +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> - <!-- no translation found for activity_resolver_use_once (2404644797149173758) --> - <skip /> + <string name="activity_resolver_use_once" msgid="2404644797149173758">"Hanya sekali"</string> </resources> diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml index 65cb688..265da95 100644 --- a/core/res/res/values-iw/strings.xml +++ b/core/res/res/values-iw/strings.xml @@ -855,12 +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> - <!-- 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="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"> @@ -1127,10 +1124,8 @@ <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="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> @@ -1324,6 +1319,5 @@ <string name="launchBrowserDefault" msgid="2057951947297614725">"להפעיל את הדפדפן?"</string> <string name="SetupCallDefault" msgid="5834948469253758575">"האם לקבל את השיחה?"</string> <string name="activity_resolver_use_always" msgid="8017770747801494933">"תמיד"</string> - <!-- no translation found for activity_resolver_use_once (2404644797149173758) --> - <skip /> + <string name="activity_resolver_use_once" msgid="2404644797149173758">"רק פעם אחת"</string> </resources> diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml index 03de346..4e3fe51 100644 --- a/core/res/res/values-ko/strings.xml +++ b/core/res/res/values-ko/strings.xml @@ -855,12 +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> - <!-- 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="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"> @@ -1127,10 +1124,8 @@ <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="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> @@ -1324,6 +1319,5 @@ <string name="launchBrowserDefault" msgid="2057951947297614725">"브라우저를 실행하시겠습니까?"</string> <string name="SetupCallDefault" msgid="5834948469253758575">"통화를 수락하시겠습니까?"</string> <string name="activity_resolver_use_always" msgid="8017770747801494933">"항상"</string> - <!-- no translation found for activity_resolver_use_once (2404644797149173758) --> - <skip /> + <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 0474391..52b7a4b 100644 --- a/core/res/res/values-lt/strings.xml +++ b/core/res/res/values-lt/strings.xml @@ -855,12 +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> - <!-- 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="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"> @@ -1127,10 +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> - <!-- no translation found for select_keyboard_layout_notification_title (1407367017263030773) --> - <skip /> - <!-- no translation found for select_keyboard_layout_notification_message (4465907700449257063) --> - <skip /> + <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> @@ -1324,6 +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> - <!-- no translation found for activity_resolver_use_once (2404644797149173758) --> - <skip /> + <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 aaed6e2..1fb76f6 100644 --- a/core/res/res/values-lv/strings.xml +++ b/core/res/res/values-lv/strings.xml @@ -855,12 +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> - <!-- 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="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"> @@ -1127,10 +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> - <!-- no translation found for select_keyboard_layout_notification_title (1407367017263030773) --> - <skip /> - <!-- no translation found for select_keyboard_layout_notification_message (4465907700449257063) --> - <skip /> + <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> @@ -1324,6 +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> - <!-- no translation found for activity_resolver_use_once (2404644797149173758) --> - <skip /> + <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 fec15b2..2168b9a 100644 --- a/core/res/res/values-ms/strings.xml +++ b/core/res/res/values-ms/strings.xml @@ -855,12 +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> - <!-- 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="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"> @@ -1127,10 +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> - <!-- no translation found for select_keyboard_layout_notification_title (1407367017263030773) --> - <skip /> - <!-- no translation found for select_keyboard_layout_notification_message (4465907700449257063) --> - <skip /> + <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> @@ -1324,6 +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> - <!-- no translation found for activity_resolver_use_once (2404644797149173758) --> - <skip /> + <string name="activity_resolver_use_once" msgid="2404644797149173758">"Hanya sekali"</string> </resources> diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml index a634006..a1cbe5a 100644 --- a/core/res/res/values-pl/strings.xml +++ b/core/res/res/values-pl/strings.xml @@ -855,12 +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> - <!-- 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="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"> @@ -1127,10 +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> - <!-- no translation found for select_keyboard_layout_notification_title (1407367017263030773) --> - <skip /> - <!-- no translation found for select_keyboard_layout_notification_message (4465907700449257063) --> - <skip /> + <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> @@ -1324,6 +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> - <!-- no translation found for activity_resolver_use_once (2404644797149173758) --> - <skip /> + <string name="activity_resolver_use_once" msgid="2404644797149173758">"Tylko raz"</string> </resources> diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml index 2a4855c..3acafb1 100644 --- a/core/res/res/values-pt/strings.xml +++ b/core/res/res/values-pt/strings.xml @@ -855,12 +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> - <!-- 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="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"> @@ -1127,10 +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> - <!-- no translation found for select_keyboard_layout_notification_title (1407367017263030773) --> - <skip /> - <!-- no translation found for select_keyboard_layout_notification_message (4465907700449257063) --> - <skip /> + <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> @@ -1324,6 +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> - <!-- no translation found for activity_resolver_use_once (2404644797149173758) --> - <skip /> + <string name="activity_resolver_use_once" msgid="2404644797149173758">"Só uma vez"</string> </resources> diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml index 90398a3..2e019d4 100644 --- a/core/res/res/values-sl/strings.xml +++ b/core/res/res/values-sl/strings.xml @@ -317,8 +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">"vezano na storitev za ljudi s posebnimi potrebami"</string> - <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Lastniku omogoča povezovanje z vmesnikom storitve za ljudi s posebnimi potrebami najvišje ravni. Tega nikoli ni treba uporabiti za navadne aplikacije."</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> diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml index 40345d1..35079c5 100644 --- a/core/res/res/values-sw/strings.xml +++ b/core/res/res/values-sw/strings.xml @@ -855,12 +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> - <!-- 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="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"> @@ -1127,10 +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> - <!-- no translation found for select_keyboard_layout_notification_title (1407367017263030773) --> - <skip /> - <!-- no translation found for select_keyboard_layout_notification_message (4465907700449257063) --> - <skip /> + <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> @@ -1324,6 +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> - <!-- no translation found for activity_resolver_use_once (2404644797149173758) --> - <skip /> + <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 8de8e5e..34e4433 100644 --- a/core/res/res/values-th/strings.xml +++ b/core/res/res/values-th/strings.xml @@ -855,12 +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> - <!-- 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="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"> @@ -1127,10 +1124,8 @@ <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="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> @@ -1324,6 +1319,5 @@ <string name="launchBrowserDefault" msgid="2057951947297614725">"เปิดเบราว์เซอร์หรือไม่"</string> <string name="SetupCallDefault" msgid="5834948469253758575">"รับสายหรือไม่"</string> <string name="activity_resolver_use_always" msgid="8017770747801494933">"ทุกครั้ง"</string> - <!-- no translation found for activity_resolver_use_once (2404644797149173758) --> - <skip /> + <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 a659e9e..666d131 100644 --- a/core/res/res/values-tl/strings.xml +++ b/core/res/res/values-tl/strings.xml @@ -855,12 +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> - <!-- 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="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"> @@ -1127,10 +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> - <!-- no translation found for select_keyboard_layout_notification_title (1407367017263030773) --> - <skip /> - <!-- no translation found for select_keyboard_layout_notification_message (4465907700449257063) --> - <skip /> + <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> @@ -1324,6 +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> - <!-- no translation found for activity_resolver_use_once (2404644797149173758) --> - <skip /> + <string name="activity_resolver_use_once" msgid="2404644797149173758">"Isang beses lang"</string> </resources> diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml index 5d06934..3e3b506 100644 --- a/core/res/res/values-uk/strings.xml +++ b/core/res/res/values-uk/strings.xml @@ -855,12 +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> - <!-- 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="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"> @@ -1127,10 +1124,8 @@ <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="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> @@ -1324,6 +1319,5 @@ <string name="launchBrowserDefault" msgid="2057951947297614725">"Запустити веб-переглядач?"</string> <string name="SetupCallDefault" msgid="5834948469253758575">"Прийняти виклик?"</string> <string name="activity_resolver_use_always" msgid="8017770747801494933">"Завжди"</string> - <!-- no translation found for activity_resolver_use_once (2404644797149173758) --> - <skip /> + <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 cce563a..af89a2d 100644 --- a/core/res/res/values-vi/strings.xml +++ b/core/res/res/values-vi/strings.xml @@ -855,12 +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> - <!-- 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="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"> @@ -1127,10 +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> - <!-- no translation found for select_keyboard_layout_notification_title (1407367017263030773) --> - <skip /> - <!-- no translation found for select_keyboard_layout_notification_message (4465907700449257063) --> - <skip /> + <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> @@ -1324,6 +1319,5 @@ <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 chọn"</string> - <!-- no translation found for activity_resolver_use_once (2404644797149173758) --> - <skip /> + <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 7cd2d9d..865761b 100644 --- a/core/res/res/values-zh-rCN/strings.xml +++ b/core/res/res/values-zh-rCN/strings.xml @@ -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> @@ -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> @@ -554,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> @@ -1111,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> diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml index 0c7d269..7966153 100644 --- a/core/res/res/values-zu/strings.xml +++ b/core/res/res/values-zu/strings.xml @@ -855,12 +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> - <!-- 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="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"> @@ -1127,10 +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> - <!-- no translation found for select_keyboard_layout_notification_title (1407367017263030773) --> - <skip /> - <!-- no translation found for select_keyboard_layout_notification_message (4465907700449257063) --> - <skip /> + <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> @@ -1324,6 +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> - <!-- no translation found for activity_resolver_use_once (2404644797149173758) --> - <skip /> + <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"> |
