diff options
Diffstat (limited to 'core/java')
40 files changed, 1136 insertions, 452 deletions
diff --git a/core/java/android/accounts/ChooseTypeAndAccountActivity.java b/core/java/android/accounts/ChooseTypeAndAccountActivity.java index 6b3b7fd..5358bc7 100644 --- a/core/java/android/accounts/ChooseTypeAndAccountActivity.java +++ b/core/java/android/accounts/ChooseTypeAndAccountActivity.java @@ -15,6 +15,8 @@ */ package android.accounts; +import com.google.android.collect.Sets; + import android.app.Activity; import android.content.Intent; import android.os.Bundle; @@ -105,6 +107,13 @@ public class ChooseTypeAndAccountActivity extends Activity private static final int SELECTED_ITEM_NONE = -1; + private Set<Account> mSetOfAllowableAccounts; + private Set<String> mSetOfRelevantAccountTypes; + private String mSelectedAccountName = null; + private boolean mSelectedAddNewAccount = false; + private boolean mAlwaysPromptForAccount = false; + private String mDescriptionOverride; + private ArrayList<Account> mAccounts; private int mPendingRequest = REQUEST_NULL; private Parcelable[] mExistingAccounts = null; @@ -120,22 +129,18 @@ public class ChooseTypeAndAccountActivity extends Activity } // 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( + mSelectedAccountName = savedInstanceState.getString( KEY_INSTANCE_STATE_SELECTED_ACCOUNT_NAME); - selectedAddNewAccount = savedInstanceState.getBoolean( + mSelectedAddNewAccount = savedInstanceState.getBoolean( KEY_INSTANCE_STATE_SELECTED_ADD_ACCOUNT, false); } else { mPendingRequest = REQUEST_NULL; @@ -144,85 +149,38 @@ public class ChooseTypeAndAccountActivity extends Activity // show is as pre-selected. Account selectedAccount = (Account) intent.getParcelableExtra(EXTRA_SELECTED_ACCOUNT); if (selectedAccount != null) { - selectedAccountName = selectedAccount.name; + mSelectedAccountName = selectedAccount.name; } } if (Log.isLoggable(TAG, Log.VERBOSE)) { - Log.v(TAG, "selected account name is " + selectedAccountName); + Log.v(TAG, "selected account name is " + mSelectedAccountName); } - // build an efficiently queryable map of account types to authenticator descriptions - final HashMap<String, AuthenticatorDescription> typeToAuthDescription = - new HashMap<String, AuthenticatorDescription>(); - for(AuthenticatorDescription desc : accountManager.getAuthenticatorTypes()) { - typeToAuthDescription.put(desc.type, desc); - } - - // Read the validAccounts, if present, and add them to the setOfAllowableAccounts - Set<Account> setOfAllowableAccounts = null; - final ArrayList<Parcelable> validAccounts = - intent.getParcelableArrayListExtra(EXTRA_ALLOWABLE_ACCOUNTS_ARRAYLIST); - if (validAccounts != null) { - setOfAllowableAccounts = new HashSet<Account>(validAccounts.size()); - for (Parcelable parcelable : validAccounts) { - setOfAllowableAccounts.add((Account)parcelable); - } - } - // An account type is relevant iff it is allowed by the caller and supported by the account - // manager. - Set<String> setOfRelevantAccountTypes = null; - final String[] allowedAccountTypes = - intent.getStringArrayExtra(EXTRA_ALLOWABLE_ACCOUNT_TYPES_STRING_ARRAY); - if (allowedAccountTypes != null) { - - setOfRelevantAccountTypes = new HashSet<String>(allowedAccountTypes.length); - Set<String> setOfAllowedAccountTypes = new HashSet<String>(allowedAccountTypes.length); - for (String type : allowedAccountTypes) { - setOfAllowedAccountTypes.add(type); - } - - AuthenticatorDescription[] descs = AccountManager.get(this).getAuthenticatorTypes(); - Set<String> supportedAccountTypes = new HashSet<String>(descs.length); - for (AuthenticatorDescription desc : descs) { - supportedAccountTypes.add(desc.type); - } + mSetOfAllowableAccounts = getAllowableAccountSet(intent); + mSetOfRelevantAccountTypes = getReleventAccountTypes(intent); + mAlwaysPromptForAccount = intent.getBooleanExtra(EXTRA_ALWAYS_PROMPT_FOR_ACCOUNT, false); + mDescriptionOverride = intent.getStringExtra(EXTRA_DESCRIPTION_TEXT_OVERRIDE); + } - for (String acctType : setOfAllowedAccountTypes) { - if (supportedAccountTypes.contains(acctType)) { - setOfRelevantAccountTypes.add(acctType); - } - } - } + @Override + protected void onResume() { + super.onResume(); + final AccountManager accountManager = AccountManager.get(this); - // Create a list of AccountInfo objects for each account that is allowable. Filter out - // 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(); - mAccounts = new ArrayList<Account>(accounts.length); - mSelectedItemIndex = SELECTED_ITEM_NONE; - for (Account account : accounts) { - if (setOfAllowableAccounts != null - && !setOfAllowableAccounts.contains(account)) { - continue; - } - if (setOfRelevantAccountTypes != null - && !setOfRelevantAccountTypes.contains(account.type)) { - continue; - } - if (account.name.equals(selectedAccountName)) { - mSelectedItemIndex = mAccounts.size(); - } - mAccounts.add(account); - } + mAccounts = getAcceptableAccountChoices(accountManager); + // In cases where the activity does not need to show an account picker, cut the chase + // and return the result directly. Eg: + // Single account -> select it directly + // No account -> launch add account activity directly if (mPendingRequest == REQUEST_NULL) { // If there are no relevant accounts and only one relevant account type go directly to // add account. Otherwise let the user choose. if (mAccounts.isEmpty()) { - if (setOfRelevantAccountTypes.size() == 1) { - runAddAccountForAuthenticator(setOfRelevantAccountTypes.iterator().next()); + if (mSetOfRelevantAccountTypes.size() == 1) { + runAddAccountForAuthenticator(mSetOfRelevantAccountTypes.iterator().next()); } else { startChooseAccountTypeActivity(); } @@ -230,61 +188,22 @@ public class ChooseTypeAndAccountActivity extends Activity } // if there is only one allowable account return it - if (!intent.getBooleanExtra(EXTRA_ALWAYS_PROMPT_FOR_ACCOUNT, false) - && mAccounts.size() == 1) { + if (!mAlwaysPromptForAccount && mAccounts.size() == 1) { Account account = mAccounts.get(0); setResultAndFinish(account.name, account.type); return; } } + String[] listItems = getListOfDisplayableOptions(mAccounts); + mSelectedItemIndex = getItemIndexToSelect( + mAccounts, mSelectedAccountName, mSelectedAddNewAccount); + // Cannot set content view until we know that mPendingRequest is not null, otherwise // would cause screen flicker. setContentView(R.layout.choose_type_and_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 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) { - mSelectedItemIndex = position; - mOkButton.setEnabled(true); - } - }); - - // If "Add account" option was previously selected by user, preserve it across - // orientation changes. - if (selectedAddNewAccount) { - mSelectedItemIndex = mAccounts.size(); - } - if (mSelectedItemIndex != SELECTED_ITEM_NONE) { - list.setItemChecked(mSelectedItemIndex, true); - if (Log.isLoggable(TAG, Log.VERBOSE)) { - Log.v(TAG, "List item " + mSelectedItemIndex + " should be selected"); - } - } + overrideDescriptionIfSupplied(mDescriptionOverride); + populateUIAccountList(listItems); // Only enable "OK" button if something has been selected. mOkButton = (Button) findViewById(android.R.id.button2); @@ -480,4 +399,137 @@ public class ChooseTypeAndAccountActivity extends Activity startActivityForResult(intent, REQUEST_CHOOSE_TYPE); mPendingRequest = REQUEST_CHOOSE_TYPE; } + + /** + * @return a value between 0 (inclusive) and accounts.size() (inclusive) or SELECTED_ITEM_NONE. + * An index value of accounts.size() indicates 'Add account' option. + */ + private int getItemIndexToSelect(ArrayList<Account> accounts, String selectedAccountName, + boolean selectedAddNewAccount) { + // If "Add account" option was previously selected by user, preserve it across + // orientation changes. + if (selectedAddNewAccount) { + return accounts.size(); + } + // search for the selected account name if present + for (int i = 0; i < accounts.size(); i++) { + if (accounts.get(i).name.equals(selectedAccountName)) { + return i; + } + } + // no account selected. + return SELECTED_ITEM_NONE; + } + + private String[] getListOfDisplayableOptions(ArrayList<Account> accounts) { + // List of options includes all accounts found together with "Add new account" as the + // last item in the list. + String[] listItems = new String[accounts.size() + 1]; + for (int i = 0; i < accounts.size(); i++) { + listItems[i] = accounts.get(i).name; + } + listItems[accounts.size()] = getResources().getString( + R.string.add_account_button_label); + return listItems; + } + + /** + * Create a list of Account objects for each account that is acceptable. Filter out + * accounts that don't match the allowable types, if provided, or that don't match the + * allowable accounts, if provided. + */ + private ArrayList<Account> getAcceptableAccountChoices(AccountManager accountManager) { + final Account[] accounts = accountManager.getAccounts(); + ArrayList<Account> accountsToPopulate = new ArrayList<Account>(accounts.length); + for (Account account : accounts) { + if (mSetOfAllowableAccounts != null + && !mSetOfAllowableAccounts.contains(account)) { + continue; + } + if (mSetOfRelevantAccountTypes != null + && !mSetOfRelevantAccountTypes.contains(account.type)) { + continue; + } + accountsToPopulate.add(account); + } + return accountsToPopulate; + } + + /** + * Return a set of account types speficied by the intent as well as supported by the + * AccountManager. + */ + private Set<String> getReleventAccountTypes(final Intent intent) { + // An account type is relevant iff it is allowed by the caller and supported by the account + // manager. + Set<String> setOfRelevantAccountTypes = null; + final String[] allowedAccountTypes = + intent.getStringArrayExtra(EXTRA_ALLOWABLE_ACCOUNT_TYPES_STRING_ARRAY); + if (allowedAccountTypes != null) { + setOfRelevantAccountTypes = Sets.newHashSet(allowedAccountTypes); + AuthenticatorDescription[] descs = AccountManager.get(this).getAuthenticatorTypes(); + Set<String> supportedAccountTypes = new HashSet<String>(descs.length); + for (AuthenticatorDescription desc : descs) { + supportedAccountTypes.add(desc.type); + } + setOfRelevantAccountTypes.retainAll(supportedAccountTypes); + } + return setOfRelevantAccountTypes; + } + + /** + * Returns a set of whitelisted accounts given by the intent or null if none specified by the + * intent. + */ + private Set<Account> getAllowableAccountSet(final Intent intent) { + Set<Account> setOfAllowableAccounts = null; + final ArrayList<Parcelable> validAccounts = + intent.getParcelableArrayListExtra(EXTRA_ALLOWABLE_ACCOUNTS_ARRAYLIST); + if (validAccounts != null) { + setOfAllowableAccounts = new HashSet<Account>(validAccounts.size()); + for (Parcelable parcelable : validAccounts) { + setOfAllowableAccounts.add((Account)parcelable); + } + } + return setOfAllowableAccounts; + } + + /** + * Overrides the description text view for the picker activity if specified by the intent. + * If not specified then makes the description invisible. + */ + private void overrideDescriptionIfSupplied(String descriptionOverride) { + TextView descriptionView = (TextView) findViewById(R.id.description); + if (!TextUtils.isEmpty(descriptionOverride)) { + descriptionView.setText(descriptionOverride); + } else { + descriptionView.setVisibility(View.GONE); + } + } + + /** + * Populates the UI ListView with the given list of items and selects an item + * based on {@code mSelectedItemIndex} member variable. + */ + private final void populateUIAccountList(String[] listItems) { + ListView list = (ListView) findViewById(android.R.id.list); + 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) { + mSelectedItemIndex = position; + mOkButton.setEnabled(true); + } + }); + if (mSelectedItemIndex != SELECTED_ITEM_NONE) { + list.setItemChecked(mSelectedItemIndex, true); + if (Log.isLoggable(TAG, Log.VERBOSE)) { + Log.v(TAG, "List item " + mSelectedItemIndex + " should be selected"); + } + } + } } diff --git a/core/java/android/app/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java index bf77f6e..eae3b1f 100644 --- a/core/java/android/app/ActivityManagerNative.java +++ b/core/java/android/app/ActivityManagerNative.java @@ -1734,6 +1734,22 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM return true; } + case REGISTER_USER_SWITCH_OBSERVER_TRANSACTION: { + data.enforceInterface(IActivityManager.descriptor); + IUserSwitchObserver observer = IUserSwitchObserver.Stub.asInterface( + data.readStrongBinder()); + registerUserSwitchObserver(observer); + return true; + } + + case UNREGISTER_USER_SWITCH_OBSERVER_TRANSACTION: { + data.enforceInterface(IActivityManager.descriptor); + IUserSwitchObserver observer = IUserSwitchObserver.Stub.asInterface( + data.readStrongBinder()); + unregisterUserSwitchObserver(observer); + return true; + } + } return super.onTransact(code, data, reply, flags); @@ -3955,5 +3971,27 @@ class ActivityManagerProxy implements IActivityManager return result; } + public void registerUserSwitchObserver(IUserSwitchObserver observer) throws RemoteException { + Parcel data = Parcel.obtain(); + Parcel reply = Parcel.obtain(); + data.writeInterfaceToken(IActivityManager.descriptor); + data.writeStrongBinder(observer != null ? observer.asBinder() : null); + mRemote.transact(REGISTER_USER_SWITCH_OBSERVER_TRANSACTION, data, reply, 0); + reply.readException(); + data.recycle(); + reply.recycle(); + } + + public void unregisterUserSwitchObserver(IUserSwitchObserver observer) throws RemoteException { + Parcel data = Parcel.obtain(); + Parcel reply = Parcel.obtain(); + data.writeInterfaceToken(IActivityManager.descriptor); + data.writeStrongBinder(observer != null ? observer.asBinder() : null); + mRemote.transact(UNREGISTER_USER_SWITCH_OBSERVER_TRANSACTION, data, reply, 0); + reply.readException(); + data.recycle(); + reply.recycle(); + } + private IBinder mRemote; } diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java index 1cd5fa2..cb4d4a1 100644 --- a/core/java/android/app/ActivityThread.java +++ b/core/java/android/app/ActivityThread.java @@ -84,7 +84,6 @@ import android.view.Window; import android.view.WindowManager; import android.view.WindowManagerGlobal; import android.renderscript.RenderScript; -import android.security.AndroidKeyStoreProvider; import com.android.internal.os.BinderInternal; import com.android.internal.os.RuntimeInit; @@ -4891,8 +4890,6 @@ public final class ActivityThread { // Set the reporter for event logging in libcore EventLogger.setReporter(new EventLoggingReporter()); - Security.addProvider(new AndroidKeyStoreProvider()); - Process.setArgV0("<pre-initialized>"); Looper.prepareMainLooper(); diff --git a/core/java/android/app/IActivityManager.java b/core/java/android/app/IActivityManager.java index 4c0e2a7..9ef375a 100644 --- a/core/java/android/app/IActivityManager.java +++ b/core/java/android/app/IActivityManager.java @@ -360,6 +360,9 @@ public interface IActivityManager extends IInterface { // manage your activity to make sure it is always the uid you expect. public int getLaunchedFromUid(IBinder activityToken) throws RemoteException; + public void registerUserSwitchObserver(IUserSwitchObserver observer) throws RemoteException; + public void unregisterUserSwitchObserver(IUserSwitchObserver observer) throws RemoteException; + /* * Private non-Binder interfaces */ @@ -609,4 +612,6 @@ public interface IActivityManager extends IInterface { int IS_INTENT_SENDER_AN_ACTIVITY_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+151; int START_ACTIVITY_AS_USER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+152; int STOP_USER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+153; + int REGISTER_USER_SWITCH_OBSERVER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+154; + int UNREGISTER_USER_SWITCH_OBSERVER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+155; } diff --git a/core/java/android/app/IUserSwitchObserver.aidl b/core/java/android/app/IUserSwitchObserver.aidl new file mode 100644 index 0000000..845897b --- /dev/null +++ b/core/java/android/app/IUserSwitchObserver.aidl @@ -0,0 +1,25 @@ +/* + * Copyright (C) 2012 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.app; + +import android.os.IRemoteCallback; + +/** {@hide} */ +oneway interface IUserSwitchObserver { + void onUserSwitching(int newUserId, IRemoteCallback reply); + void onUserSwitchComplete(int newUserId); +} diff --git a/core/java/android/app/IWallpaperManager.aidl b/core/java/android/app/IWallpaperManager.aidl index 69f64a1..3efd3c0 100644 --- a/core/java/android/app/IWallpaperManager.aidl +++ b/core/java/android/app/IWallpaperManager.aidl @@ -52,6 +52,11 @@ interface IWallpaperManager { void clearWallpaper(); /** + * Return whether there is a wallpaper set with the given name. + */ + boolean hasNamedWallpaper(String name); + + /** * Sets the dimension hint for the wallpaper. These hints indicate the desired * minimum width and height for the wallpaper. */ diff --git a/core/java/android/app/WallpaperManager.java b/core/java/android/app/WallpaperManager.java index 1ad2e6d..9c0064e 100644 --- a/core/java/android/app/WallpaperManager.java +++ b/core/java/android/app/WallpaperManager.java @@ -590,6 +590,25 @@ public class WallpaperManager { } /** + * Return whether any users are currently set to use the wallpaper + * with the given resource ID. That is, their wallpaper has been + * set through {@link #setResource(int)} with the same resource id. + */ + public boolean hasResourceWallpaper(int resid) { + if (sGlobals.mService == null) { + Log.w(TAG, "WallpaperService not running"); + return false; + } + try { + Resources resources = mContext.getResources(); + String name = "res:" + resources.getResourceName(resid); + return sGlobals.mService.hasNamedWallpaper(name); + } catch (RemoteException e) { + return false; + } + } + + /** * Returns the desired minimum width for the wallpaper. Callers of * {@link #setBitmap(android.graphics.Bitmap)} or * {@link #setStream(java.io.InputStream)} should check this value diff --git a/core/java/android/appwidget/AppWidgetHost.java b/core/java/android/appwidget/AppWidgetHost.java index c76bf91..51a81c5 100644 --- a/core/java/android/appwidget/AppWidgetHost.java +++ b/core/java/android/appwidget/AppWidgetHost.java @@ -24,8 +24,10 @@ import android.os.Handler; import android.os.IBinder; import android.os.Looper; import android.os.Message; +import android.os.Process; import android.os.RemoteException; import android.os.ServiceManager; +import android.os.UserHandle; import android.util.DisplayMetrics; import android.util.TypedValue; import android.widget.RemoteViews; @@ -115,18 +117,22 @@ public class AppWidgetHost { private OnClickHandler mOnClickHandler; public AppWidgetHost(Context context, int hostId) { - this(context, hostId, null); + this(context, hostId, null, Looper.getMainLooper()); } /** * @hide */ - public AppWidgetHost(Context context, int hostId, OnClickHandler handler) { + public AppWidgetHost(Context context, int hostId, OnClickHandler handler, Looper looper) { mContext = context; mHostId = hostId; mOnClickHandler = handler; - mHandler = new UpdateHandler(context.getMainLooper()); + mHandler = new UpdateHandler(looper); mDisplayMetrics = context.getResources().getDisplayMetrics(); + bindService(); + } + + private static void bindService() { synchronized (sServiceLock) { if (sService == null) { IBinder b = ServiceManager.getService(Context.APPWIDGET_SERVICE); @@ -190,6 +196,32 @@ public class AppWidgetHost { } /** + * Get a appWidgetId for a host in the calling process. + * + * @return a appWidgetId + * @hide + */ + public static int allocateAppWidgetIdForHost(String packageName, int hostId) { + checkCallerIsSystem(); + try { + if (sService == null) { + bindService(); + } + return sService.allocateAppWidgetId(packageName, hostId); + } catch (RemoteException e) { + throw new RuntimeException("system server dead?", e); + } + } + + private static void checkCallerIsSystem() { + int uid = Process.myUid(); + if (UserHandle.getAppId(uid) == Process.SYSTEM_UID || uid == 0) { + return; + } + throw new SecurityException("Disallowed call for uid " + uid); + } + + /** * Stop listening to changes for this AppWidget. */ public void deleteAppWidgetId(int appWidgetId) { @@ -205,6 +237,22 @@ public class AppWidgetHost { } /** + * Stop listening to changes for this AppWidget. + * @hide + */ + public static void deleteAppWidgetIdForHost(int appWidgetId) { + checkCallerIsSystem(); + try { + if (sService == null) { + bindService(); + } + sService.deleteAppWidgetId(appWidgetId); + } catch (RemoteException e) { + throw new RuntimeException("system server dead?", e); + } + } + + /** * Remove all records about this host from the AppWidget manager. * <ul> * <li>Call this when initializing your database, as it might be because of a data wipe.</li> diff --git a/core/java/android/appwidget/AppWidgetManager.java b/core/java/android/appwidget/AppWidgetManager.java index 100a2b8..6fb6dc4 100644 --- a/core/java/android/appwidget/AppWidgetManager.java +++ b/core/java/android/appwidget/AppWidgetManager.java @@ -216,6 +216,28 @@ public class AppWidgetManager { public static final String EXTRA_CUSTOM_EXTRAS = "customExtras"; /** + * An intent extra to pass to the AppWidget picker which allows the picker to filter + * the list based on the {@link AppWidgetProviderInfo#widgetCategory}. + * + * @hide + */ + public static final String EXTRA_CATEGORY_FILTER = "categoryFilter"; + + /** + * An intent extra to pass to the AppWidget picker which allows the picker to filter + * the list based on the {@link AppWidgetProviderInfo#widgetFeatures}. + * @hide + */ + public static final String EXTRA_FEATURES_FILTER = "featuresFilter"; + + /** + * An intent extra to pass to the AppWidget picker to specify whether or not to sort + * the list of caller-specified extra AppWidgets along with the rest of the AppWidgets + * @hide + */ + public static final String EXTRA_CUSTOM_SORT = "customSort"; + + /** * A sentiel value that the AppWidget manager will never return as a appWidgetId. */ public static final int INVALID_APPWIDGET_ID = 0; diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java index bca5ade..fad3e10 100644 --- a/core/java/android/content/Intent.java +++ b/core/java/android/content/Intent.java @@ -1473,7 +1473,7 @@ public class Intent implements Parcelable, Cloneable { * Broadcast Action: A new application package has been installed on the * device. The data contains the name of the package. Note that the * newly installed package does <em>not</em> receive this broadcast. - * <p>My include the following extras: + * <p>May include the following extras: * <ul> * <li> {@link #EXTRA_UID} containing the integer uid assigned to the new package. * <li> {@link #EXTRA_REPLACING} is set to true if this is following @@ -1489,7 +1489,7 @@ public class Intent implements Parcelable, Cloneable { * Broadcast Action: A new version of an application package has been * installed, replacing an existing version that was previously installed. * The data contains the name of the package. - * <p>My include the following extras: + * <p>May include the following extras: * <ul> * <li> {@link #EXTRA_UID} containing the integer uid assigned to the new package. * </ul> @@ -2287,17 +2287,62 @@ public class Intent implements Parcelable, Cloneable { "android.intent.action.PRE_BOOT_COMPLETED"; /** + * Sent the first time a user is starting, to allow system apps to + * perform one time initialization. (This will not be seen by third + * party applications because a newly initialized user does not have any + * third party applications installed for it.) This is sent early in + * starting the user, around the time the home app is started, before + * {@link #ACTION_BOOT_COMPLETED} is sent. + */ + public static final String ACTION_USER_INITIALIZE = + "android.intent.action.USER_INITIALIZE"; + + /** + * Sent when a user switch is happening, causing the process's user to be + * brought to the foreground. This is only sent to receivers registered + * through {@link Context#registerReceiver(BroadcastReceiver, IntentFilter) + * Context.registerReceiver}. It is sent to the user that is going to the + * foreground. + */ + public static final String ACTION_USER_FOREGROUND = + "android.intent.action.USER_FOREGROUND"; + + /** + * Sent when a user switch is happening, causing the process's user to be + * sent to the background. This is only sent to receivers registered + * through {@link Context#registerReceiver(BroadcastReceiver, IntentFilter) + * Context.registerReceiver}. It is sent to the user that is going to the + * background. + */ + public static final String ACTION_USER_BACKGROUND = + "android.intent.action.USER_BACKGROUND"; + + /** * Broadcast sent to the system when a user is added. Carries an extra EXTRA_USER_HANDLE that has the - * userHandle of the new user. + * userHandle of the new user. It is sent to all running users. You must hold + * {@link android.Manifest.permission#MANAGE_USERS} to receive this broadcast. * @hide */ public static final String ACTION_USER_ADDED = "android.intent.action.USER_ADDED"; /** + * Broadcast sent to the system when a user is started. Carries an extra EXTRA_USER_HANDLE that has + * the userHandle of the user. This is only sent to + * registered receivers, not manifest receivers. It is sent to the user + * that has been started. + * @hide + */ + public static final String ACTION_USER_STARTED = + "android.intent.action.USER_STARTED"; + + /** * Broadcast sent to the system when a user is stopped. Carries an extra EXTRA_USER_HANDLE that has * the userHandle of the user. This is similar to {@link #ACTION_PACKAGE_RESTARTED}, - * but for an entire user instead of a specific package. + * but for an entire user instead of a specific package. This is only sent to + * registered receivers, not manifest receivers. It is sent to all running + * users <em>except</em> the one that has just been stopped (which is no + * longer running). * @hide */ public static final String ACTION_USER_STOPPED = @@ -2305,7 +2350,9 @@ public class Intent implements Parcelable, Cloneable { /** * Broadcast sent to the system when a user is removed. Carries an extra EXTRA_USER_HANDLE that has - * the userHandle of the user. + * the userHandle of the user. It is sent to all running users except the + * one that has been removed. You must hold + * {@link android.Manifest.permission#MANAGE_USERS} to receive this broadcast. * @hide */ public static final String ACTION_USER_REMOVED = @@ -2313,7 +2360,10 @@ public class Intent implements Parcelable, Cloneable { /** * Broadcast sent to the system when the user switches. Carries an extra EXTRA_USER_HANDLE that has - * the userHandle of the user to become the current one. + * the userHandle of the user to become the current one. This is only sent to + * registered receivers, not manifest receivers. It is sent to all running users. + * You must hold + * {@link android.Manifest.permission#MANAGE_USERS} to receive this broadcast. * @hide */ public static final String ACTION_USER_SWITCHED = diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java index 5399583..4784d7f 100644 --- a/core/java/android/content/pm/PackageManager.java +++ b/core/java/android/content/pm/PackageManager.java @@ -1151,6 +1151,22 @@ public abstract class PackageManager { = "android.content.pm.extra.VERIFICATION_INSTALL_FLAGS"; /** + * Extra field name for the uid of who is requesting to install + * the package. + * + * @hide + */ + public static final String EXTRA_VERIFICATION_INSTALLER_UID + = "android.content.pm.extra.VERIFICATION_INSTALLER_UID"; + + /** + * Extra field name for the package name of a package pending verification. + * + * @hide + */ + public static final String EXTRA_VERIFICATION_PACKAGE_NAME + = "android.content.pm.extra.VERIFICATION_PACKAGE_NAME"; + /** * Extra field name for the result of a verification, either * {@link #VERIFICATION_ALLOW}, or {@link #VERIFICATION_REJECT}. * Passed to package verifiers after a package is verified. @@ -1159,6 +1175,14 @@ public abstract class PackageManager { = "android.content.pm.extra.VERIFICATION_RESULT"; /** + * Extra field name for the version code of a package pending verification. + * + * @hide + */ + public static final String EXTRA_VERIFICATION_VERSION_CODE + = "android.content.pm.extra.VERIFICATION_VERSION_CODE"; + + /** * Retrieve overall information about an application package that is * installed on the system. * <p> diff --git a/core/java/android/content/pm/UserInfo.java b/core/java/android/content/pm/UserInfo.java index 6bc9a1f..a06aba9 100644 --- a/core/java/android/content/pm/UserInfo.java +++ b/core/java/android/content/pm/UserInfo.java @@ -30,6 +30,12 @@ public class UserInfo implements Parcelable { public static final int FLAG_MASK_USER_TYPE = 0x0000003F; /** + * *************************** NOTE *************************** + * These flag values CAN NOT CHANGE because they are written + * directly to storage. + */ + + /** * Primary user. Only one user can have this flag set. Meaning of this * flag TBD. */ @@ -52,6 +58,11 @@ public class UserInfo implements Parcelable { */ public static final int FLAG_RESTRICTED = 0x00000008; + /** + * Indicates that this user has gone through its first-time initialization. + */ + public static final int FLAG_INITIALIZED = 0x00000010; + public int id; public int serialNumber; public String name; diff --git a/core/java/android/content/pm/VerificationParams.java b/core/java/android/content/pm/VerificationParams.java index 9bec87e..6454de0 100644 --- a/core/java/android/content/pm/VerificationParams.java +++ b/core/java/android/content/pm/VerificationParams.java @@ -39,6 +39,9 @@ public class VerificationParams implements Parcelable { /** HTTP referrer URI associated with the originatingURI. */ private final Uri mReferrer; + /** UID of application requesting the install */ + private int mInstallerUid; + /** * An object that holds the digest of the package which can be used to * verify ownership. @@ -63,6 +66,7 @@ public class VerificationParams implements Parcelable { mOriginatingURI = originatingURI; mReferrer = referrer; mManifestDigest = manifestDigest; + mInstallerUid = -1; } public Uri getVerificationURI() { @@ -81,6 +85,15 @@ public class VerificationParams implements Parcelable { return mManifestDigest; } + /** @return -1 when not set */ + public int getInstallerUid() { + return mInstallerUid; + } + + public void setInstallerUid(int uid) { + mInstallerUid = uid; + } + @Override public int describeContents() { return 0; @@ -126,6 +139,10 @@ public class VerificationParams implements Parcelable { return false; } + if (mInstallerUid != other.mInstallerUid) { + return false; + } + return true; } @@ -137,6 +154,7 @@ public class VerificationParams implements Parcelable { hash += 7 * (mOriginatingURI==null?1:mOriginatingURI.hashCode()); hash += 11 * (mReferrer==null?1:mReferrer.hashCode()); hash += 13 * (mManifestDigest==null?1:mManifestDigest.hashCode()); + hash += 17 * mInstallerUid; return hash; } @@ -153,6 +171,8 @@ public class VerificationParams implements Parcelable { sb.append(mReferrer.toString()); sb.append(",mManifestDigest="); sb.append(mManifestDigest.toString()); + sb.append(",mInstallerUid="); + sb.append(mInstallerUid); sb.append('}'); return sb.toString(); @@ -164,6 +184,7 @@ public class VerificationParams implements Parcelable { dest.writeParcelable(mOriginatingURI, 0); dest.writeParcelable(mReferrer, 0); dest.writeParcelable(mManifestDigest, 0); + dest.writeInt(mInstallerUid); } @@ -172,6 +193,7 @@ public class VerificationParams implements Parcelable { mOriginatingURI = source.readParcelable(Uri.class.getClassLoader()); mReferrer = source.readParcelable(Uri.class.getClassLoader()); mManifestDigest = source.readParcelable(ManifestDigest.class.getClassLoader()); + mInstallerUid = source.readInt(); } public static final Parcelable.Creator<VerificationParams> CREATOR = diff --git a/core/java/android/net/INetworkPolicyManager.aidl b/core/java/android/net/INetworkPolicyManager.aidl index 3250ae7..df6057e 100644 --- a/core/java/android/net/INetworkPolicyManager.aidl +++ b/core/java/android/net/INetworkPolicyManager.aidl @@ -30,9 +30,9 @@ import android.net.NetworkTemplate; interface INetworkPolicyManager { /** Control UID policies. */ - void setAppPolicy(int appId, int policy); - int getAppPolicy(int appId); - int[] getAppsWithPolicy(int policy); + void setUidPolicy(int uid, int policy); + int getUidPolicy(int uid); + int[] getUidsWithPolicy(int policy); boolean isUidForeground(int uid); diff --git a/core/java/android/net/NetworkPolicyManager.java b/core/java/android/net/NetworkPolicyManager.java index 07bfd4b..2cd1f9b 100644 --- a/core/java/android/net/NetworkPolicyManager.java +++ b/core/java/android/net/NetworkPolicyManager.java @@ -26,6 +26,7 @@ import android.content.pm.PackageManager; import android.content.pm.PackageManager.NameNotFoundException; import android.content.pm.Signature; import android.os.RemoteException; +import android.os.UserHandle; import android.text.format.Time; import com.google.android.collect.Sets; @@ -72,29 +73,29 @@ public class NetworkPolicyManager { } /** - * Set policy flags for specific application. + * Set policy flags for specific UID. * * @param policy {@link #POLICY_NONE} or combination of flags like * {@link #POLICY_REJECT_METERED_BACKGROUND}. */ - public void setAppPolicy(int appId, int policy) { + public void setUidPolicy(int uid, int policy) { try { - mService.setAppPolicy(appId, policy); + mService.setUidPolicy(uid, policy); } catch (RemoteException e) { } } - public int getAppPolicy(int appId) { + public int getUidPolicy(int uid) { try { - return mService.getAppPolicy(appId); + return mService.getUidPolicy(uid); } catch (RemoteException e) { return POLICY_NONE; } } - public int[] getAppsWithPolicy(int policy) { + public int[] getUidsWithPolicy(int policy) { try { - return mService.getAppsWithPolicy(policy); + return mService.getUidsWithPolicy(policy); } catch (RemoteException e) { return new int[0]; } @@ -236,8 +237,7 @@ public class NetworkPolicyManager { @Deprecated public static boolean isUidValidForPolicy(Context context, int uid) { // first, quick-reject non-applications - if (uid < android.os.Process.FIRST_APPLICATION_UID - || uid > android.os.Process.LAST_APPLICATION_UID) { + if (!UserHandle.isApp(uid)) { return false; } diff --git a/core/java/android/net/http/CertificateChainValidator.java b/core/java/android/net/http/CertificateChainValidator.java index 6ad8fe3..f66075d 100644 --- a/core/java/android/net/http/CertificateChainValidator.java +++ b/core/java/android/net/http/CertificateChainValidator.java @@ -168,7 +168,13 @@ public class CertificateChainValidator { } try { - SSLParametersImpl.getDefaultTrustManager().checkServerTrusted(chain, authType); + X509TrustManager x509TrustManager = SSLParametersImpl.getDefaultTrustManager(); + if (x509TrustManager instanceof TrustManagerImpl) { + TrustManagerImpl trustManager = (TrustManagerImpl) x509TrustManager; + trustManager.checkServerTrusted(chain, authType, domain); + } else { + x509TrustManager.checkServerTrusted(chain, authType); + } return null; // No errors. } catch (GeneralSecurityException e) { if (HttpLog.LOGV) { diff --git a/core/java/android/os/UserHandle.java b/core/java/android/os/UserHandle.java index 22994ff..cc96152 100644 --- a/core/java/android/os/UserHandle.java +++ b/core/java/android/os/UserHandle.java @@ -87,15 +87,19 @@ public final class UserHandle implements Parcelable { /** @hide */ public static final boolean isIsolated(int uid) { - uid = getAppId(uid); - return uid >= Process.FIRST_ISOLATED_UID && uid <= Process.LAST_ISOLATED_UID; + if (uid > 0) { + final int appId = getAppId(uid); + return appId >= Process.FIRST_ISOLATED_UID && appId <= Process.LAST_ISOLATED_UID; + } else { + return false; + } } /** @hide */ public static boolean isApp(int uid) { if (uid > 0) { - uid = UserHandle.getAppId(uid); - return uid >= Process.FIRST_APPLICATION_UID && uid <= Process.LAST_APPLICATION_UID; + final int appId = getAppId(uid); + return appId >= Process.FIRST_APPLICATION_UID && appId <= Process.LAST_APPLICATION_UID; } else { return false; } diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java index 9ea523d..f3dbecb 100644 --- a/core/java/android/provider/Settings.java +++ b/core/java/android/provider/Settings.java @@ -754,22 +754,29 @@ public final class Settings { } public String getStringForUser(ContentResolver cr, String name, final int userHandle) { - long newValuesVersion = SystemProperties.getLong(mVersionSystemProperty, 0); + final boolean isSelf = (userHandle == UserHandle.myUserId()); + if (isSelf) { + long newValuesVersion = SystemProperties.getLong(mVersionSystemProperty, 0); - synchronized (this) { - if (mValuesVersion != newValuesVersion) { - if (LOCAL_LOGV || false) { - Log.v(TAG, "invalidate [" + mUri.getLastPathSegment() + "]: current " + - newValuesVersion + " != cached " + mValuesVersion); - } + // Our own user's settings data uses a client-side cache + synchronized (this) { + if (mValuesVersion != newValuesVersion) { + if (LOCAL_LOGV || false) { + Log.v(TAG, "invalidate [" + mUri.getLastPathSegment() + "]: current " + + newValuesVersion + " != cached " + mValuesVersion); + } - mValues.clear(); - mValuesVersion = newValuesVersion; - } + mValues.clear(); + mValuesVersion = newValuesVersion; + } - if (mValues.containsKey(name)) { - return mValues.get(name); // Could be null, that's OK -- negative caching + if (mValues.containsKey(name)) { + return mValues.get(name); // Could be null, that's OK -- negative caching + } } + } else { + if (LOCAL_LOGV) Log.v(TAG, "get setting for user " + userHandle + + " by user " + UserHandle.myUserId() + " so skipping cache"); } IContentProvider cp = lazyGetProvider(cr); @@ -788,8 +795,15 @@ public final class Settings { Bundle b = cp.call(mCallGetCommand, name, args); if (b != null) { String value = b.getPairValue(); - synchronized (this) { - mValues.put(name, value); + // Don't update our cache for reads of other users' data + if (isSelf) { + synchronized (this) { + mValues.put(name, value); + } + } else { + if (LOCAL_LOGV) Log.i(TAG, "call-query of user " + userHandle + + " by " + UserHandle.myUserId() + + " so not updating cache"); } return value; } @@ -3187,6 +3201,20 @@ public final class Settings { public static final String LOCK_SCREEN_OWNER_INFO = "lock_screen_owner_info"; /** + * Id of the time appwidget on the lockscreen, or -1 if none + * @hide + */ + public static final String LOCK_SCREEN_CLOCK_APPWIDGET_ID = + "lock_screen_clock_appwidget_id"; + + /** + * Id of the user-selected appwidget on the lockscreen, or -1 if none + * @hide + */ + public static final String LOCK_SCREEN_USER_SELECTED_APPWIDGET_ID = + "lock_screen_user_selected_appwidget_id"; + + /** * This preference enables showing the owner info on LockScren. * @hide */ @@ -3535,46 +3563,51 @@ public final class Settings { public static final String TTS_ENABLED_PLUGINS = "tts_enabled_plugins"; /** - * Whether to notify the user of open networks. - * <p> - * If not connected and the scan results have an open network, we will - * put this notification up. If we attempt to connect to a network or - * the open network(s) disappear, we remove the notification. When we - * show the notification, we will not show it again for - * {@link android.provider.Settings.Secure#WIFI_NETWORKS_AVAILABLE_REPEAT_DELAY} time. + * @deprecated Use {@link android.provider.Settings.Global#WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON} + * instead. */ + @Deprecated public static final String WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON = - "wifi_networks_available_notification_on"; + Global.WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON; /** + * @deprecated Moved to Global namespace * {@hide} */ + @Deprecated public static final String WIMAX_NETWORKS_AVAILABLE_NOTIFICATION_ON = - "wimax_networks_available_notification_on"; + Global.WIMAX_NETWORKS_AVAILABLE_NOTIFICATION_ON; /** - * Delay (in seconds) before repeating the Wi-Fi networks available notification. - * Connecting to a network will reset the timer. + * @deprecated Use {@link android.provider.Settings.Global#WIFI_NETWORKS_AVAILABLE_REPEAT_DELAY} + * instead. */ + @Deprecated public static final String WIFI_NETWORKS_AVAILABLE_REPEAT_DELAY = - "wifi_networks_available_repeat_delay"; + Global.WIFI_NETWORKS_AVAILABLE_REPEAT_DELAY; /** - * 802.11 country code in ISO 3166 format + * @deprecated Use {@link android.provider.Settings.Global#WIFI_COUNTRY_CODE} + * instead. * @hide */ - public static final String WIFI_COUNTRY_CODE = "wifi_country_code"; + @Deprecated + public static final String WIFI_COUNTRY_CODE = Global.WIFI_COUNTRY_CODE; /** - * When the number of open networks exceeds this number, the - * least-recently-used excess networks will be removed. + * @deprecated Use {@link android.provider.Settings.Global#WIFI_NUM_OPEN_NETWORKS_KEPT} + * instead. */ - public static final String WIFI_NUM_OPEN_NETWORKS_KEPT = "wifi_num_open_networks_kept"; + @Deprecated + public static final String WIFI_NUM_OPEN_NETWORKS_KEPT = + Global.WIFI_NUM_OPEN_NETWORKS_KEPT; /** - * Whether the Wi-Fi should be on. Only the Wi-Fi service should touch this. + * @deprecated Use {@link android.provider.Settings.Global#WIFI_ON} + * instead. */ - public static final String WIFI_ON = "wifi_on"; + @Deprecated + public static final String WIFI_ON = Global.WIFI_ON; /** * Used to save the Wifi_ON state prior to tethering. @@ -3582,8 +3615,10 @@ public final class Settings { * the user turns off tethering. * * @hide + * @deprecated moved to Global */ - public static final String WIFI_SAVED_STATE = "wifi_saved_state"; + @Deprecated + public static final String WIFI_SAVED_STATE = Global.WIFI_SAVED_STATE; /** * AP SSID @@ -4192,24 +4227,30 @@ public final class Settings { * When idle, it is possible for the device to be switched from Wi-Fi to * the mobile data network. * @hide + * @deprecated Moved to Global */ - public static final String WIFI_IDLE_MS = "wifi_idle_ms"; + @Deprecated + public static final String WIFI_IDLE_MS = Global.WIFI_IDLE_MS; /** * The interval in milliseconds to issue wake up scans when wifi needs * to connect. This is necessary to connect to an access point when * device is on the move and the screen is off. * @hide + * @deprecated Moved to Global */ + @Deprecated public static final String WIFI_FRAMEWORK_SCAN_INTERVAL_MS = - "wifi_framework_scan_interval_ms"; + Global.WIFI_FRAMEWORK_SCAN_INTERVAL_MS; /** * The interval in milliseconds to scan as used by the wifi supplicant * @hide + * @deprecated Moved to Global */ + @Deprecated public static final String WIFI_SUPPLICANT_SCAN_INTERVAL_MS = - "wifi_supplicant_scan_interval_ms"; + Global.WIFI_SUPPLICANT_SCAN_INTERVAL_MS; /** * @deprecated Moved to Settings.Global diff --git a/core/java/android/service/wallpaper/IWallpaperConnection.aidl b/core/java/android/service/wallpaper/IWallpaperConnection.aidl index b09ccab..f9c5aaa 100644 --- a/core/java/android/service/wallpaper/IWallpaperConnection.aidl +++ b/core/java/android/service/wallpaper/IWallpaperConnection.aidl @@ -24,5 +24,6 @@ import android.service.wallpaper.IWallpaperEngine; */ interface IWallpaperConnection { void attachEngine(IWallpaperEngine engine); + void engineShown(IWallpaperEngine engine); ParcelFileDescriptor setWallpaper(String name); } diff --git a/core/java/android/service/wallpaper/WallpaperService.java b/core/java/android/service/wallpaper/WallpaperService.java index efa8911..86bbc55 100644 --- a/core/java/android/service/wallpaper/WallpaperService.java +++ b/core/java/android/service/wallpaper/WallpaperService.java @@ -1020,6 +1020,12 @@ public abstract class WallpaperService extends Service { mEngine = engine; mActiveEngines.add(engine); engine.attach(this); + try { + mConnection.engineShown(this); + } catch (RemoteException e) { + Log.w(TAG, "Wallpaper host disappeared", e); + return; + } return; } case DO_DETACH: { diff --git a/core/java/android/text/format/DateUtils.java b/core/java/android/text/format/DateUtils.java index 211453d..0babcc5 100644 --- a/core/java/android/text/format/DateUtils.java +++ b/core/java/android/text/format/DateUtils.java @@ -29,6 +29,8 @@ import java.util.GregorianCalendar; import java.util.Locale; import java.util.TimeZone; +import libcore.icu.LocaleData; + /** * This class contains various date-related utilities for creating text for things like * elapsed time and date ranges, strings for days of the week and months, and AM/PM text etc. @@ -36,102 +38,6 @@ import java.util.TimeZone; public class DateUtils { private static final Object sLock = new Object(); - private static final int[] sDaysLong = new int[] { - com.android.internal.R.string.day_of_week_long_sunday, - com.android.internal.R.string.day_of_week_long_monday, - com.android.internal.R.string.day_of_week_long_tuesday, - com.android.internal.R.string.day_of_week_long_wednesday, - com.android.internal.R.string.day_of_week_long_thursday, - com.android.internal.R.string.day_of_week_long_friday, - com.android.internal.R.string.day_of_week_long_saturday, - }; - private static final int[] sDaysMedium = new int[] { - com.android.internal.R.string.day_of_week_medium_sunday, - com.android.internal.R.string.day_of_week_medium_monday, - com.android.internal.R.string.day_of_week_medium_tuesday, - com.android.internal.R.string.day_of_week_medium_wednesday, - com.android.internal.R.string.day_of_week_medium_thursday, - com.android.internal.R.string.day_of_week_medium_friday, - com.android.internal.R.string.day_of_week_medium_saturday, - }; - private static final int[] sDaysShort = new int[] { - com.android.internal.R.string.day_of_week_short_sunday, - com.android.internal.R.string.day_of_week_short_monday, - com.android.internal.R.string.day_of_week_short_tuesday, - com.android.internal.R.string.day_of_week_short_wednesday, - com.android.internal.R.string.day_of_week_short_thursday, - com.android.internal.R.string.day_of_week_short_friday, - com.android.internal.R.string.day_of_week_short_saturday, - }; - private static final int[] sDaysShortest = new int[] { - com.android.internal.R.string.day_of_week_shortest_sunday, - com.android.internal.R.string.day_of_week_shortest_monday, - com.android.internal.R.string.day_of_week_shortest_tuesday, - com.android.internal.R.string.day_of_week_shortest_wednesday, - com.android.internal.R.string.day_of_week_shortest_thursday, - com.android.internal.R.string.day_of_week_shortest_friday, - com.android.internal.R.string.day_of_week_shortest_saturday, - }; - private static final int[] sMonthsStandaloneLong = new int [] { - com.android.internal.R.string.month_long_standalone_january, - com.android.internal.R.string.month_long_standalone_february, - com.android.internal.R.string.month_long_standalone_march, - com.android.internal.R.string.month_long_standalone_april, - com.android.internal.R.string.month_long_standalone_may, - com.android.internal.R.string.month_long_standalone_june, - com.android.internal.R.string.month_long_standalone_july, - com.android.internal.R.string.month_long_standalone_august, - com.android.internal.R.string.month_long_standalone_september, - com.android.internal.R.string.month_long_standalone_october, - com.android.internal.R.string.month_long_standalone_november, - com.android.internal.R.string.month_long_standalone_december, - }; - private static final int[] sMonthsLong = new int [] { - com.android.internal.R.string.month_long_january, - com.android.internal.R.string.month_long_february, - com.android.internal.R.string.month_long_march, - com.android.internal.R.string.month_long_april, - com.android.internal.R.string.month_long_may, - com.android.internal.R.string.month_long_june, - com.android.internal.R.string.month_long_july, - com.android.internal.R.string.month_long_august, - com.android.internal.R.string.month_long_september, - com.android.internal.R.string.month_long_october, - com.android.internal.R.string.month_long_november, - com.android.internal.R.string.month_long_december, - }; - private static final int[] sMonthsMedium = new int [] { - com.android.internal.R.string.month_medium_january, - com.android.internal.R.string.month_medium_february, - com.android.internal.R.string.month_medium_march, - com.android.internal.R.string.month_medium_april, - com.android.internal.R.string.month_medium_may, - com.android.internal.R.string.month_medium_june, - com.android.internal.R.string.month_medium_july, - com.android.internal.R.string.month_medium_august, - com.android.internal.R.string.month_medium_september, - com.android.internal.R.string.month_medium_october, - com.android.internal.R.string.month_medium_november, - com.android.internal.R.string.month_medium_december, - }; - private static final int[] sMonthsShortest = new int [] { - com.android.internal.R.string.month_shortest_january, - com.android.internal.R.string.month_shortest_february, - com.android.internal.R.string.month_shortest_march, - com.android.internal.R.string.month_shortest_april, - com.android.internal.R.string.month_shortest_may, - com.android.internal.R.string.month_shortest_june, - com.android.internal.R.string.month_shortest_july, - com.android.internal.R.string.month_shortest_august, - com.android.internal.R.string.month_shortest_september, - com.android.internal.R.string.month_shortest_october, - com.android.internal.R.string.month_shortest_november, - com.android.internal.R.string.month_shortest_december, - }; - private static final int[] sAmPm = new int[] { - com.android.internal.R.string.am, - com.android.internal.R.string.pm, - }; private static Configuration sLastConfig; private static java.text.DateFormat sStatusTimeFormat; private static String sElapsedFormatMMSS; @@ -161,12 +67,17 @@ public class DateUtils public static final int FORMAT_NO_YEAR = 0x00008; public static final int FORMAT_SHOW_DATE = 0x00010; public static final int FORMAT_NO_MONTH_DAY = 0x00020; + @Deprecated public static final int FORMAT_12HOUR = 0x00040; + @Deprecated public static final int FORMAT_24HOUR = 0x00080; + @Deprecated public static final int FORMAT_CAP_AMPM = 0x00100; public static final int FORMAT_NO_NOON = 0x00200; + @Deprecated public static final int FORMAT_CAP_NOON = 0x00400; public static final int FORMAT_NO_MIDNIGHT = 0x00800; + @Deprecated public static final int FORMAT_CAP_MIDNIGHT = 0x01000; /** * @deprecated Use @@ -181,19 +92,25 @@ public class DateUtils public static final int FORMAT_NUMERIC_DATE = 0x20000; public static final int FORMAT_ABBREV_RELATIVE = 0x40000; public static final int FORMAT_ABBREV_ALL = 0x80000; + @Deprecated public static final int FORMAT_CAP_NOON_MIDNIGHT = (FORMAT_CAP_NOON | FORMAT_CAP_MIDNIGHT); + @Deprecated public static final int FORMAT_NO_NOON_MIDNIGHT = (FORMAT_NO_NOON | FORMAT_NO_MIDNIGHT); // Date and time format strings that are constant and don't need to be // translated. /** * This is not actually the preferred 24-hour date format in all locales. + * @deprecated use {@link java.text.SimpleDateFormat} instead. */ + @Deprecated public static final String HOUR_MINUTE_24 = "%H:%M"; public static final String MONTH_FORMAT = "%B"; /** * This is not actually a useful month name in all locales. + * @deprecated use {@link java.text.SimpleDateFormat} instead. */ + @Deprecated public static final String ABBREV_MONTH_FORMAT = "%b"; public static final String NUMERIC_MONTH_FORMAT = "%m"; public static final String MONTH_DAY_FORMAT = "%-d"; @@ -207,6 +124,7 @@ public class DateUtils // The index is constructed from a bit-wise OR of the boolean values: // {showTime, showYear, showWeekDay}. For example, if showYear and // showWeekDay are both true, then the index would be 3. + /** @deprecated do not use. */ public static final int sameYearTable[] = { com.android.internal.R.string.same_year_md1_md2, com.android.internal.R.string.same_year_wday1_md1_wday2_md2, @@ -233,6 +151,7 @@ public class DateUtils // The index is constructed from a bit-wise OR of the boolean values: // {showTime, showYear, showWeekDay}. For example, if showYear and // showWeekDay are both true, then the index would be 3. + /** @deprecated do not use. */ public static final int sameMonthTable[] = { com.android.internal.R.string.same_month_md1_md2, com.android.internal.R.string.same_month_wday1_md1_wday2_md2, @@ -259,7 +178,9 @@ public class DateUtils * * @more <p> * e.g. "Sunday" or "January" + * @deprecated use {@link java.text.SimpleDateFormat} instead. */ + @Deprecated public static final int LENGTH_LONG = 10; /** @@ -268,7 +189,9 @@ public class DateUtils * * @more <p> * e.g. "Sun" or "Jan" + * @deprecated use {@link java.text.SimpleDateFormat} instead. */ + @Deprecated public static final int LENGTH_MEDIUM = 20; /** @@ -278,14 +201,18 @@ public class DateUtils * <p>e.g. "Su" or "Jan" * <p>In most languages, the results returned for LENGTH_SHORT will be the same as * the results returned for {@link #LENGTH_MEDIUM}. + * @deprecated use {@link java.text.SimpleDateFormat} instead. */ + @Deprecated public static final int LENGTH_SHORT = 30; /** * Request an even shorter abbreviated version of the name. * Do not use this. Currently this will always return the same result * as {@link #LENGTH_SHORT}. + * @deprecated use {@link java.text.SimpleDateFormat} instead. */ + @Deprecated public static final int LENGTH_SHORTER = 40; /** @@ -295,7 +222,9 @@ public class DateUtils * <p>e.g. "S", "T", "T" or "J" * <p>In some languages, the results returned for LENGTH_SHORTEST will be the same as * the results returned for {@link #LENGTH_SHORT}. + * @deprecated use {@link java.text.SimpleDateFormat} instead. */ + @Deprecated public static final int LENGTH_SHORTEST = 50; /** @@ -309,20 +238,21 @@ public class DateUtils * Undefined lengths will return {@link #LENGTH_MEDIUM} * but may return something different in the future. * @throws IndexOutOfBoundsException if the dayOfWeek is out of bounds. + * @deprecated use {@link java.text.SimpleDateFormat} instead. */ + @Deprecated public static String getDayOfWeekString(int dayOfWeek, int abbrev) { - int[] list; + LocaleData d = LocaleData.get(Locale.getDefault()); + String[] names; switch (abbrev) { - case LENGTH_LONG: list = sDaysLong; break; - case LENGTH_MEDIUM: list = sDaysMedium; break; - case LENGTH_SHORT: list = sDaysShort; break; - case LENGTH_SHORTER: list = sDaysShort; break; - case LENGTH_SHORTEST: list = sDaysShortest; break; - default: list = sDaysMedium; break; + case LENGTH_LONG: names = d.longWeekdayNames; break; + case LENGTH_MEDIUM: names = d.shortWeekdayNames; break; + case LENGTH_SHORT: names = d.shortWeekdayNames; break; // TODO + case LENGTH_SHORTER: names = d.shortWeekdayNames; break; // TODO + case LENGTH_SHORTEST: names = d.tinyWeekdayNames; break; + default: names = d.shortWeekdayNames; break; } - - Resources r = Resources.getSystem(); - return r.getString(list[dayOfWeek - Calendar.SUNDAY]); + return names[dayOfWeek]; } /** @@ -330,10 +260,11 @@ public class DateUtils * @param ampm Either {@link Calendar#AM Calendar.AM} or {@link Calendar#PM Calendar.PM}. * @throws IndexOutOfBoundsException if the ampm is out of bounds. * @return Localized version of "AM" or "PM". + * @deprecated use {@link java.text.SimpleDateFormat} instead. */ + @Deprecated public static String getAMPMString(int ampm) { - Resources r = Resources.getSystem(); - return r.getString(sAmPm[ampm - Calendar.AM]); + return LocaleData.get(Locale.getDefault()).amPm[ampm - Calendar.AM]; } /** @@ -345,24 +276,25 @@ public class DateUtils * Undefined lengths will return {@link #LENGTH_MEDIUM} * but may return something different in the future. * @return Localized month of the year. + * @deprecated use {@link java.text.SimpleDateFormat} instead. */ + @Deprecated public static String getMonthString(int month, int abbrev) { - // Note that here we use sMonthsMedium for MEDIUM, SHORT and SHORTER. + // Note that here we use d.shortMonthNames for MEDIUM, SHORT and SHORTER. // This is a shortcut to not spam the translators with too many variations // of the same string. If we find that in a language the distinction // is necessary, we can can add more without changing this API. - int[] list; + LocaleData d = LocaleData.get(Locale.getDefault()); + String[] names; switch (abbrev) { - case LENGTH_LONG: list = sMonthsLong; break; - case LENGTH_MEDIUM: list = sMonthsMedium; break; - case LENGTH_SHORT: list = sMonthsMedium; break; - case LENGTH_SHORTER: list = sMonthsMedium; break; - case LENGTH_SHORTEST: list = sMonthsShortest; break; - default: list = sMonthsMedium; break; + case LENGTH_LONG: names = d.longMonthNames; break; + case LENGTH_MEDIUM: names = d.shortMonthNames; break; + case LENGTH_SHORT: names = d.shortMonthNames; break; + case LENGTH_SHORTER: names = d.shortMonthNames; break; + case LENGTH_SHORTEST: names = d.tinyMonthNames; break; + default: names = d.shortMonthNames; break; } - - Resources r = Resources.getSystem(); - return r.getString(list[month - Calendar.JANUARY]); + return names[month]; } /** @@ -378,25 +310,26 @@ public class DateUtils * but may return something different in the future. * @return Localized month of the year. * @hide Pending API council approval + * @deprecated use {@link java.text.SimpleDateFormat} instead. */ + @Deprecated public static String getStandaloneMonthString(int month, int abbrev) { - // Note that here we use sMonthsMedium for MEDIUM, SHORT and SHORTER. + // Note that here we use d.shortMonthNames for MEDIUM, SHORT and SHORTER. // This is a shortcut to not spam the translators with too many variations // of the same string. If we find that in a language the distinction // is necessary, we can can add more without changing this API. - int[] list; + LocaleData d = LocaleData.get(Locale.getDefault()); + String[] names; switch (abbrev) { - case LENGTH_LONG: list = sMonthsStandaloneLong; + case LENGTH_LONG: names = d.longStandAloneMonthNames; break; - case LENGTH_MEDIUM: list = sMonthsMedium; break; - case LENGTH_SHORT: list = sMonthsMedium; break; - case LENGTH_SHORTER: list = sMonthsMedium; break; - case LENGTH_SHORTEST: list = sMonthsShortest; break; - default: list = sMonthsMedium; break; + case LENGTH_MEDIUM: names = d.shortMonthNames; break; + case LENGTH_SHORT: names = d.shortMonthNames; break; + case LENGTH_SHORTER: names = d.shortMonthNames; break; + case LENGTH_SHORTEST: names = d.tinyMonthNames; break; + default: names = d.shortMonthNames; break; } - - Resources r = Resources.getSystem(); - return r.getString(list[month - Calendar.JANUARY]); + return names[month]; } /** @@ -619,14 +552,19 @@ public class DateUtils int days = Math.abs(currentDay - startDay); boolean past = (today > day); + // TODO: some locales name other days too, such as de_DE's "Vorgestern" (today - 2). + Locale locale = r.getConfiguration().locale; + if (locale == null) { + locale = Locale.getDefault(); + } if (days == 1) { if (past) { - return r.getString(com.android.internal.R.string.yesterday); + return LocaleData.get(locale).yesterday; } else { - return r.getString(com.android.internal.R.string.tomorrow); + return LocaleData.get(locale).tomorrow; } } else if (days == 0) { - return r.getString(com.android.internal.R.string.today); + return LocaleData.get(locale).today; } int resId; diff --git a/core/java/android/text/format/Time.java b/core/java/android/text/format/Time.java index b0b18da..45d5a70 100644 --- a/core/java/android/text/format/Time.java +++ b/core/java/android/text/format/Time.java @@ -21,6 +21,8 @@ import android.content.res.Resources; import java.util.Locale; import java.util.TimeZone; +import libcore.icu.LocaleData; + /** * An alternative to the {@link java.util.Calendar} and * {@link java.util.GregorianCalendar} classes. An instance of the Time class represents @@ -317,73 +319,21 @@ public class Time { Locale locale = Locale.getDefault(); if (sLocale == null || locale == null || !(locale.equals(sLocale))) { - Resources r = Resources.getSystem(); + LocaleData localeData = LocaleData.get(locale); + + sAm = localeData.amPm[0]; + sPm = localeData.amPm[1]; - sShortMonths = new String[] { - r.getString(com.android.internal.R.string.month_medium_january), - r.getString(com.android.internal.R.string.month_medium_february), - r.getString(com.android.internal.R.string.month_medium_march), - r.getString(com.android.internal.R.string.month_medium_april), - r.getString(com.android.internal.R.string.month_medium_may), - r.getString(com.android.internal.R.string.month_medium_june), - r.getString(com.android.internal.R.string.month_medium_july), - r.getString(com.android.internal.R.string.month_medium_august), - r.getString(com.android.internal.R.string.month_medium_september), - r.getString(com.android.internal.R.string.month_medium_october), - r.getString(com.android.internal.R.string.month_medium_november), - r.getString(com.android.internal.R.string.month_medium_december), - }; - sLongMonths = new String[] { - r.getString(com.android.internal.R.string.month_long_january), - r.getString(com.android.internal.R.string.month_long_february), - r.getString(com.android.internal.R.string.month_long_march), - r.getString(com.android.internal.R.string.month_long_april), - r.getString(com.android.internal.R.string.month_long_may), - r.getString(com.android.internal.R.string.month_long_june), - r.getString(com.android.internal.R.string.month_long_july), - r.getString(com.android.internal.R.string.month_long_august), - r.getString(com.android.internal.R.string.month_long_september), - r.getString(com.android.internal.R.string.month_long_october), - r.getString(com.android.internal.R.string.month_long_november), - r.getString(com.android.internal.R.string.month_long_december), - }; - sLongStandaloneMonths = new String[] { - r.getString(com.android.internal.R.string.month_long_standalone_january), - r.getString(com.android.internal.R.string.month_long_standalone_february), - r.getString(com.android.internal.R.string.month_long_standalone_march), - r.getString(com.android.internal.R.string.month_long_standalone_april), - r.getString(com.android.internal.R.string.month_long_standalone_may), - r.getString(com.android.internal.R.string.month_long_standalone_june), - r.getString(com.android.internal.R.string.month_long_standalone_july), - r.getString(com.android.internal.R.string.month_long_standalone_august), - r.getString(com.android.internal.R.string.month_long_standalone_september), - r.getString(com.android.internal.R.string.month_long_standalone_october), - r.getString(com.android.internal.R.string.month_long_standalone_november), - r.getString(com.android.internal.R.string.month_long_standalone_december), - }; - sShortWeekdays = new String[] { - r.getString(com.android.internal.R.string.day_of_week_medium_sunday), - r.getString(com.android.internal.R.string.day_of_week_medium_monday), - r.getString(com.android.internal.R.string.day_of_week_medium_tuesday), - r.getString(com.android.internal.R.string.day_of_week_medium_wednesday), - r.getString(com.android.internal.R.string.day_of_week_medium_thursday), - r.getString(com.android.internal.R.string.day_of_week_medium_friday), - r.getString(com.android.internal.R.string.day_of_week_medium_saturday), - }; - sLongWeekdays = new String[] { - r.getString(com.android.internal.R.string.day_of_week_long_sunday), - r.getString(com.android.internal.R.string.day_of_week_long_monday), - r.getString(com.android.internal.R.string.day_of_week_long_tuesday), - r.getString(com.android.internal.R.string.day_of_week_long_wednesday), - r.getString(com.android.internal.R.string.day_of_week_long_thursday), - r.getString(com.android.internal.R.string.day_of_week_long_friday), - r.getString(com.android.internal.R.string.day_of_week_long_saturday), - }; + sShortMonths = localeData.shortMonthNames; + sLongMonths = localeData.longMonthNames; + sLongStandaloneMonths = localeData.longStandAloneMonthNames; + sShortWeekdays = localeData.shortWeekdayNames; + sLongWeekdays = localeData.longWeekdayNames; + + Resources r = Resources.getSystem(); sTimeOnlyFormat = r.getString(com.android.internal.R.string.time_of_day); sDateOnlyFormat = r.getString(com.android.internal.R.string.month_day_year); sDateTimeFormat = r.getString(com.android.internal.R.string.date_and_time); - sAm = r.getString(com.android.internal.R.string.am); - sPm = r.getString(com.android.internal.R.string.pm); sLocale = locale; } diff --git a/core/java/android/util/NtpTrustedTime.java b/core/java/android/util/NtpTrustedTime.java index 2179ff3..602a68c 100644 --- a/core/java/android/util/NtpTrustedTime.java +++ b/core/java/android/util/NtpTrustedTime.java @@ -59,10 +59,10 @@ public class NtpTrustedTime implements TrustedTime { final long defaultTimeout = res.getInteger( com.android.internal.R.integer.config_ntpTimeout); - final String secureServer = Settings.Secure.getString( - resolver, Settings.Secure.NTP_SERVER); - final long timeout = Settings.Secure.getLong( - resolver, Settings.Secure.NTP_TIMEOUT, defaultTimeout); + final String secureServer = Settings.Global.getString( + resolver, Settings.Global.NTP_SERVER); + final long timeout = Settings.Global.getLong( + resolver, Settings.Global.NTP_TIMEOUT, defaultTimeout); final String server = secureServer != null ? secureServer : defaultServer; sSingleton = new NtpTrustedTime(server, timeout); @@ -71,7 +71,7 @@ public class NtpTrustedTime implements TrustedTime { return sSingleton; } - /** {@inheritDoc} */ + @Override public boolean forceRefresh() { if (mServer == null) { // missing server, so no trusted time available @@ -91,12 +91,12 @@ public class NtpTrustedTime implements TrustedTime { } } - /** {@inheritDoc} */ + @Override public boolean hasCache() { return mHasCache; } - /** {@inheritDoc} */ + @Override public long getCacheAge() { if (mHasCache) { return SystemClock.elapsedRealtime() - mCachedNtpElapsedRealtime; @@ -105,7 +105,7 @@ public class NtpTrustedTime implements TrustedTime { } } - /** {@inheritDoc} */ + @Override public long getCacheCertainty() { if (mHasCache) { return mCachedNtpCertainty; @@ -114,7 +114,7 @@ public class NtpTrustedTime implements TrustedTime { } } - /** {@inheritDoc} */ + @Override public long currentTimeMillis() { if (!mHasCache) { throw new IllegalStateException("Missing authoritative time source"); diff --git a/core/java/android/view/Display.java b/core/java/android/view/Display.java index 8ac84f7..cf58458 100644 --- a/core/java/android/view/Display.java +++ b/core/java/android/view/Display.java @@ -79,6 +79,40 @@ public final class Display { public static final int DEFAULT_DISPLAY = 0; /** + * Display flag: Indicates that the display supports secure video output. + * <p> + * This flag is used to indicate that the display supports content protection + * mechanisms for secure video output at the display interface, such as HDCP. + * These mechanisms may be used to protect secure content as it leaves the device. + * </p><p> + * While mirroring content to multiple displays, it can happen that certain + * display devices support secure video output while other display devices do not. + * The secure content will be shown only on the display devices that support + * secure video output and will be blanked on other display devices that do + * not support secure video output. + * </p><p> + * This flag mainly applies to external display devices such as HDMI or + * Wifi display. Built-in display devices are usually considered secure. + * </p> + * + * @hide pending review + */ + public static final int FLAG_SUPPORTS_SECURE_VIDEO_OUTPUT = 1 << 0; + + /** + * Display flag: Indicates that the display supports secure in-memory video buffers. + * <p> + * This flag is used to indicate that the display supports content protection + * mechanisms for in-memory video buffers, such as secure memory areas. + * These mechanisms may be used to protect secure video buffers in memory from + * the video decoder to the display compositor and the video interface. + * </p> + * + * @hide pending review + */ + public static final int FLAG_SUPPORTS_SECURE_VIDEO_BUFFERS = 1 << 1; + + /** * Internal method to create a display. * Applications should use {@link android.view.WindowManager#getDefaultDisplay()} * or {@link android.hardware.display.DisplayManager#getDisplay} @@ -158,6 +192,20 @@ public final class Display { } /** + * Returns a combination of flags that describe the capabilities of the display. + * + * @return The display flags. + * + * @hide pending review + */ + public int getFlags() { + synchronized (this) { + updateDisplayInfoLocked(); + return mDisplayInfo.flags; + } + } + + /** * Gets the compatibility info used by this display instance. * * @return The compatibility info holder, or null if none is required. diff --git a/core/java/android/view/DisplayInfo.java b/core/java/android/view/DisplayInfo.java index b728d71..c968ec5 100644 --- a/core/java/android/view/DisplayInfo.java +++ b/core/java/android/view/DisplayInfo.java @@ -34,6 +34,11 @@ public final class DisplayInfo implements Parcelable { public int layerStack; /** + * Display flags. + */ + public int flags; + + /** * The human-readable name of the display. */ public String name; @@ -189,6 +194,7 @@ public final class DisplayInfo implements Parcelable { public void copyFrom(DisplayInfo other) { layerStack = other.layerStack; + flags = other.flags; name = other.name; appWidth = other.appWidth; appHeight = other.appHeight; @@ -207,6 +213,7 @@ public final class DisplayInfo implements Parcelable { public void readFromParcel(Parcel source) { layerStack = source.readInt(); + flags = source.readInt(); name = source.readString(); appWidth = source.readInt(); appHeight = source.readInt(); @@ -226,6 +233,7 @@ public final class DisplayInfo implements Parcelable { @Override public void writeToParcel(Parcel dest, int flags) { dest.writeInt(layerStack); + dest.writeInt(flags); dest.writeString(name); dest.writeInt(appWidth); dest.writeInt(appHeight); @@ -286,6 +294,17 @@ public final class DisplayInfo implements Parcelable { + ", rotation " + rotation + ", density " + logicalDensityDpi + ", " + physicalXDpi + " x " + physicalYDpi + " dpi" - + ", layerStack " + layerStack + "}"; + + ", layerStack " + layerStack + flagsToString(flags) + "}"; + } + + private static String flagsToString(int flags) { + StringBuilder result = new StringBuilder(); + if ((flags & Display.FLAG_SUPPORTS_SECURE_VIDEO_OUTPUT) != 0) { + result.append(", FLAG_SUPPORTS_SECURE_VIDEO_OUTPUT"); + } + if ((flags & Display.FLAG_SUPPORTS_SECURE_VIDEO_BUFFERS) != 0) { + result.append(", FLAG_SUPPORTS_SECURE_VIDEO_BUFFERS"); + } + return result.toString(); } } diff --git a/core/java/android/view/GestureDetector.java b/core/java/android/view/GestureDetector.java index 4bbdd4e..9ddb32e 100644 --- a/core/java/android/view/GestureDetector.java +++ b/core/java/android/view/GestureDetector.java @@ -482,6 +482,27 @@ public class GestureDetector { case MotionEvent.ACTION_POINTER_UP: mDownFocusX = mLastFocusX = focusX; mDownFocusY = mLastFocusY = focusY; + + // Check the dot product of current velocities. + // If the pointer that left was opposing another velocity vector, clear. + mVelocityTracker.computeCurrentVelocity(1000, mMaximumFlingVelocity); + final int upIndex = ev.getActionIndex(); + final int id1 = ev.getPointerId(upIndex); + final float x1 = mVelocityTracker.getXVelocity(id1); + final float y1 = mVelocityTracker.getYVelocity(id1); + for (int i = 0; i < count; i++) { + if (i == upIndex) continue; + + final int id2 = ev.getPointerId(i); + final float x = x1 * mVelocityTracker.getXVelocity(id2); + final float y = y1 * mVelocityTracker.getYVelocity(id2); + + final float dot = x + y; + if (dot < 0) { + mVelocityTracker.clear(); + break; + } + } break; case MotionEvent.ACTION_DOWN: diff --git a/core/java/android/view/ScaleGestureDetector.java b/core/java/android/view/ScaleGestureDetector.java index bcb8800..fa03139 100644 --- a/core/java/android/view/ScaleGestureDetector.java +++ b/core/java/android/view/ScaleGestureDetector.java @@ -137,6 +137,7 @@ public class ScaleGestureDetector { private long mPrevTime; private boolean mInProgress; private int mSpanSlop; + private int mMinSpan; /** * Consistency verifier for debugging purposes. @@ -149,6 +150,8 @@ public class ScaleGestureDetector { mContext = context; mListener = listener; mSpanSlop = ViewConfiguration.get(context).getScaledTouchSlop() * 2; + mMinSpan = context.getResources().getDimensionPixelSize( + com.android.internal.R.dimen.config_minScalingSpan); } /** @@ -209,8 +212,11 @@ public class ScaleGestureDetector { float devSumX = 0, devSumY = 0; for (int i = 0; i < count; i++) { if (skipIndex == i) continue; - devSumX += Math.abs(event.getX(i) - focusX); - devSumY += Math.abs(event.getY(i) - focusY); + + // Average touch major and touch minor and convert the resulting diameter into a radius. + final float touchSize = (event.getTouchMajor(i) + event.getTouchMinor(i)) / 4; + devSumX += Math.abs(event.getX(i) - focusX) + touchSize; + devSumY += Math.abs(event.getY(i) - focusY) + touchSize; } final float devX = devSumX / div; final float devY = devSumY / div; @@ -228,7 +234,7 @@ public class ScaleGestureDetector { final boolean wasInProgress = mInProgress; mFocusX = focusX; mFocusY = focusY; - if (mInProgress && (span == 0 || configChanged)) { + if (mInProgress && (span < mMinSpan || configChanged)) { mListener.onScaleEnd(this); mInProgress = false; mInitialSpan = span; @@ -238,7 +244,7 @@ public class ScaleGestureDetector { mPrevSpanY = mCurrSpanY = spanY; mInitialSpan = mPrevSpan = mCurrSpan = span; } - if (!mInProgress && span != 0 && + if (!mInProgress && span >= mMinSpan && (wasInProgress || Math.abs(span - mInitialSpan) > mSpanSlop)) { mPrevSpanX = mCurrSpanX = spanX; mPrevSpanY = mCurrSpanY = spanY; diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java index 8f77663..03f9b72 100644 --- a/core/java/android/view/View.java +++ b/core/java/android/view/View.java @@ -2759,6 +2759,23 @@ public class View implements Drawable.Callback, KeyEvent.Callback, private CharSequence mContentDescription; /** + * Specifies the id of a view for which this view serves as a label for + * accessibility purposes. + */ + private int mLabelForId = View.NO_ID; + + /** + * Predicate for matching labeled view id with its label for + * accessibility purposes. + */ + private MatchLabelForPredicate mMatchLabelForPredicate; + + /** + * Predicate for matching a view by its id. + */ + private MatchIdPredicate mMatchIdPredicate; + + /** * Cache the paddingRight set by the user to append to the scrollbar's size. * * @hide @@ -3370,6 +3387,9 @@ public class View implements Drawable.Callback, KeyEvent.Callback, case com.android.internal.R.styleable.View_contentDescription: setContentDescription(a.getString(attr)); break; + case com.android.internal.R.styleable.View_labelFor: + setLabelFor(a.getResourceId(attr, NO_ID)); + break; case com.android.internal.R.styleable.View_soundEffectsEnabled: if (!a.getBoolean(attr, true)) { viewFlagValues &= ~SOUND_EFFECTS_ENABLED; @@ -4837,6 +4857,28 @@ public class View implements Drawable.Callback, KeyEvent.Callback, info.setParent((View) parent); } + if (mID != View.NO_ID) { + View rootView = getRootView(); + if (rootView == null) { + rootView = this; + } + View label = rootView.findLabelForView(this, mID); + if (label != null) { + info.setLabeledBy(label); + } + } + + if (mLabelForId != View.NO_ID) { + View rootView = getRootView(); + if (rootView == null) { + rootView = this; + } + View labeled = rootView.findViewInsideOutShouldExist(this, mLabelForId); + if (labeled != null) { + info.setLabelFor(labeled); + } + } + info.setVisibleToUser(isVisibleToUser()); info.setPackageName(mContext.getPackageName()); @@ -4888,6 +4930,14 @@ public class View implements Drawable.Callback, KeyEvent.Callback, } } + private View findLabelForView(View view, int labeledId) { + if (mMatchLabelForPredicate == null) { + mMatchLabelForPredicate = new MatchLabelForPredicate(); + } + mMatchLabelForPredicate.mLabeledId = labeledId; + return findViewByPredicateInsideOut(view, mMatchLabelForPredicate); + } + /** * Computes whether this view is visible to the user. Such a view is * attached, visible, all its predecessors are visible, it is not clipped @@ -5059,6 +5109,32 @@ public class View implements Drawable.Callback, KeyEvent.Callback, } /** + * Gets the id of a view for which this view serves as a label for + * accessibility purposes. + * + * @return The labeled view id. + */ + @ViewDebug.ExportedProperty(category = "accessibility") + public int getLabelFor() { + return mLabelForId; + } + + /** + * Sets the id of a view for which this view serves as a label for + * accessibility purposes. + * + * @param id The labeled view id. + */ + @RemotableViewMethod + public void setLabelFor(int id) { + mLabelForId = id; + if (mLabelForId != View.NO_ID + && mID == View.NO_ID) { + mID = generateViewId(); + } + } + + /** * Invoked whenever this view loses focus, either by losing window focus or by losing * focus within its window. This method can be used to clear any state tied to the * focus. For instance, if a button is held pressed with the trackball and the window @@ -6110,17 +6186,14 @@ public class View implements Drawable.Callback, KeyEvent.Callback, return null; } - private View findViewInsideOutShouldExist(View root, final int childViewId) { - View result = root.findViewByPredicateInsideOut(this, new Predicate<View>() { - @Override - public boolean apply(View t) { - return t.mID == childViewId; - } - }); - + private View findViewInsideOutShouldExist(View root, int id) { + if (mMatchIdPredicate == null) { + mMatchIdPredicate = new MatchIdPredicate(); + } + mMatchIdPredicate.mId = id; + View result = root.findViewByPredicateInsideOut(this, mMatchIdPredicate); if (result == null) { - Log.w(VIEW_LOG_TAG, "couldn't find next focus view specified " - + "by user for id " + childViewId); + Log.w(VIEW_LOG_TAG, "couldn't find view with id " + id); } return result; } @@ -14922,6 +14995,9 @@ public class View implements Drawable.Callback, KeyEvent.Callback, */ public void setId(int id) { mID = id; + if (mID == View.NO_ID && mLabelForId != View.NO_ID) { + mID = generateViewId(); + } } /** @@ -18008,4 +18084,22 @@ public class View implements Drawable.Callback, KeyEvent.Callback, return null; } } + + private class MatchIdPredicate implements Predicate<View> { + public int mId; + + @Override + public boolean apply(View view) { + return (view.mID == mId); + } + } + + private class MatchLabelForPredicate implements Predicate<View> { + private int mLabeledId; + + @Override + public boolean apply(View view) { + return (view.mLabelForId == mLabeledId); + } + } } diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java index 47419bb..d6a0203 100644 --- a/core/java/android/view/ViewRootImpl.java +++ b/core/java/android/view/ViewRootImpl.java @@ -832,8 +832,8 @@ public final class ViewRootImpl implements ViewParent, void invalidateWorld(View view) { view.invalidate(); if (view instanceof ViewGroup) { - ViewGroup parent = (ViewGroup)view; - for (int i=0; i<parent.getChildCount(); i++) { + ViewGroup parent = (ViewGroup) view; + for (int i = 0; i < parent.getChildCount(); i++) { invalidateWorld(parent.getChildAt(i)); } } @@ -2998,7 +2998,9 @@ public final class ViewRootImpl implements ViewParent, handleDispatchDoneAnimating(); } break; case MSG_INVALIDATE_WORLD: { - invalidateWorld(mView); + if (mView != null) { + invalidateWorld(mView); + } } break; } } diff --git a/core/java/android/view/accessibility/AccessibilityEvent.java b/core/java/android/view/accessibility/AccessibilityEvent.java index 1a2a194..1500905 100644 --- a/core/java/android/view/accessibility/AccessibilityEvent.java +++ b/core/java/android/view/accessibility/AccessibilityEvent.java @@ -424,6 +424,28 @@ import java.util.List; * </ul> * </p> * <p> + * <b>Touch interaction start</b> - represents the event of starting a touch + * interaction, which is the user starts touching the screen.</br> + * <em>Type:</em> {@link #TYPE_TOUCH_INTERACTION_START}</br> + * <em>Properties:</em></br> + * <ul> + * <li>{@link #getEventType()} - The type of the event.</li> + * </ul> + * <em>Note:</em> This event is fired only by the system and is not passed to the + * view tree to be populated.</br> + * </p> + * <p> + * <b>Touch interaction end</b> - represents the event of ending a touch + * interaction, which is the user stops touching the screen.</br> + * <em>Type:</em> {@link #TYPE_TOUCH_INTERACTION_END}</br> + * <em>Properties:</em></br> + * <ul> + * <li>{@link #getEventType()} - The type of the event.</li> + * </ul> + * <em>Note:</em> This event is fired only by the system and is not passed to the + * view tree to be populated.</br> + * </p> + * <p> * <b>Touch exploration gesture start</b> - represents the event of starting a touch * exploring gesture.</br> * <em>Type:</em> {@link #TYPE_TOUCH_EXPLORATION_GESTURE_START}</br> @@ -431,15 +453,8 @@ import java.util.List; * <ul> * <li>{@link #getEventType()} - The type of the event.</li> * </ul> - * <em>Note:</em> This event type is not dispatched to descendants though - * {@link android.view.View#dispatchPopulateAccessibilityEvent(AccessibilityEvent) - * View.dispatchPopulateAccessibilityEvent(AccessibilityEvent)}, hence the event - * source {@link android.view.View} and the sub-tree rooted at it will not receive - * calls to {@link android.view.View#onPopulateAccessibilityEvent(AccessibilityEvent) - * View.onPopulateAccessibilityEvent(AccessibilityEvent)}. The preferred way to add - * text content to such events is by setting the - * {@link android.R.styleable#View_contentDescription contentDescription} of the source - * view.</br> + * <em>Note:</em> This event is fired only by the system and is not passed to the + * view tree to be populated.</br> * </p> * <p> * <b>Touch exploration gesture end</b> - represents the event of ending a touch @@ -449,15 +464,30 @@ import java.util.List; * <ul> * <li>{@link #getEventType()} - The type of the event.</li> * </ul> - * <em>Note:</em> This event type is not dispatched to descendants though - * {@link android.view.View#dispatchPopulateAccessibilityEvent(AccessibilityEvent) - * View.dispatchPopulateAccessibilityEvent(AccessibilityEvent)}, hence the event - * source {@link android.view.View} and the sub-tree rooted at it will not receive - * calls to {@link android.view.View#onPopulateAccessibilityEvent(AccessibilityEvent) - * View.onPopulateAccessibilityEvent(AccessibilityEvent)}. The preferred way to add - * text content to such events is by setting the - * {@link android.R.styleable#View_contentDescription contentDescription} of the source - * view.</br> + * <em>Note:</em> This event is fired only by the system and is not passed to the + * view tree to be populated.</br> + * </p> + * <p> + * <b>Touch gesture detection start</b> - represents the event of starting a user + * gesture detection.</br> + * <em>Type:</em> {@link #TYPE_GESTURE_DETECTION_START}</br> + * <em>Properties:</em></br> + * <ul> + * <li>{@link #getEventType()} - The type of the event.</li> + * </ul> + * <em>Note:</em> This event is fired only by the system and is not passed to the + * view tree to be populated.</br> + * </p> + * <p> + * <b>Touch gesture detection end</b> - represents the event of ending a user + * gesture detection.</br> + * <em>Type:</em> {@link #TYPE_GESTURE_DETECTION_END}</br> + * <em>Properties:</em></br> + * <ul> + * <li>{@link #getEventType()} - The type of the event.</li> + * </ul> + * <em>Note:</em> This event is fired only by the system and is not passed to the + * view tree to be populated.</br> * </p> * <p> * <b>MISCELLANEOUS TYPES</b></br> @@ -610,6 +640,26 @@ public final class AccessibilityEvent extends AccessibilityRecord implements Par public static final int TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY = 0x00020000; /** + * Represents the event of beginning gesture detection. + */ + public static final int TYPE_GESTURE_DETECTION_START = 0x00040000; + + /** + * Represents the event of ending gesture detection. + */ + public static final int TYPE_GESTURE_DETECTION_END = 0x00080000; + + /** + * Represents the event of the user starting to touch the screen. + */ + public static final int TYPE_TOUCH_INTERACTION_START = 0x00100000; + + /** + * Represents the event of the user ending to touch the screen. + */ + public static final int TYPE_TOUCH_INTERACTION_END = 0x00200000; + + /** * Mask for {@link AccessibilityEvent} all types. * * @see #TYPE_VIEW_CLICKED @@ -628,6 +678,10 @@ public final class AccessibilityEvent extends AccessibilityRecord implements Par * @see #TYPE_VIEW_TEXT_SELECTION_CHANGED * @see #TYPE_ANNOUNCEMENT * @see #TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY + * @see #TYPE_GESTURE_DETECTION_START + * @see #TYPE_GESTURE_DETECTION_END + * @see #TYPE_TOUCH_INTERACTION_START + * @see #TYPE_TOUCH_INTERACTION_END */ public static final int TYPES_ALL_MASK = 0xFFFFFFFF; @@ -1120,6 +1174,14 @@ public final class AccessibilityEvent extends AccessibilityRecord implements Par return "TYPE_VIEW_ACCESSIBILITY_FOCUS_CLEARED"; case TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY: return "TYPE_CURRENT_AT_GRANULARITY_MOVEMENT_CHANGED"; + case TYPE_GESTURE_DETECTION_START: + return "TYPE_GESTURE_DETECTION_START"; + case TYPE_GESTURE_DETECTION_END: + return "TYPE_GESTURE_DETECTION_END"; + case TYPE_TOUCH_INTERACTION_START: + return "TYPE_TOUCH_INTERACTION_START"; + case TYPE_TOUCH_INTERACTION_END: + return "TYPE_TOUCH_INTERACTION_END"; default: return null; } diff --git a/core/java/android/view/accessibility/AccessibilityNodeInfo.java b/core/java/android/view/accessibility/AccessibilityNodeInfo.java index 768744b..1dc2487 100644 --- a/core/java/android/view/accessibility/AccessibilityNodeInfo.java +++ b/core/java/android/view/accessibility/AccessibilityNodeInfo.java @@ -365,6 +365,8 @@ public class AccessibilityNodeInfo implements Parcelable { private int mWindowId = UNDEFINED; private long mSourceNodeId = ROOT_NODE_ID; private long mParentNodeId = ROOT_NODE_ID; + private long mLabelForId = ROOT_NODE_ID; + private long mLabeledById = ROOT_NODE_ID; private int mBooleanProperties; private final Rect mBoundsInParent = new Rect(); @@ -1233,6 +1235,120 @@ public class AccessibilityNodeInfo implements Parcelable { } /** + * Sets the view for which the view represented by this info serves as a + * label for accessibility purposes. + * + * @param labeled The view for which this info serves as a label. + */ + public void setLabelFor(View labeled) { + setLabelFor(labeled, UNDEFINED); + } + + /** + * Sets the view for which the view represented by this info serves as a + * label for accessibility purposes. If <code>virtualDescendantId</code> + * is {@link View#NO_ID} the root is set as the labeled. + * <p> + * A virtual descendant is an imaginary View that is reported as a part of the view + * hierarchy for accessibility purposes. This enables custom views that draw complex + * content to report themselves as a tree of virtual views, thus conveying their + * logical structure. + * </p> + * <p> + * <strong>Note:</strong> Cannot be called from an + * {@link android.accessibilityservice.AccessibilityService}. + * This class is made immutable before being delivered to an AccessibilityService. + * </p> + * + * @param root The root whose virtual descendant serves as a label. + * @param virtualDescendantId The id of the virtual descendant. + */ + public void setLabelFor(View root, int virtualDescendantId) { + enforceNotSealed(); + final int rootAccessibilityViewId = (root != null) + ? root.getAccessibilityViewId() : UNDEFINED; + mLabelForId = makeNodeId(rootAccessibilityViewId, virtualDescendantId); + } + + /** + * Gets the node info for which the view represented by this info serves as + * a label for accessibility purposes. + * <p> + * <strong>Note:</strong> It is a client responsibility to recycle the + * received info by calling {@link AccessibilityNodeInfo#recycle()} + * to avoid creating of multiple instances. + * </p> + * + * @return The labeled info. + */ + public AccessibilityNodeInfo getLabelFor() { + enforceSealed(); + if (!canPerformRequestOverConnection(mLabelForId)) { + return null; + } + AccessibilityInteractionClient client = AccessibilityInteractionClient.getInstance(); + return client.findAccessibilityNodeInfoByAccessibilityId(mConnectionId, + mWindowId, mLabelForId, FLAG_PREFETCH_DESCENDANTS | FLAG_PREFETCH_SIBLINGS); + } + + /** + * Sets the view which serves as the label of the view represented by + * this info for accessibility purposes. + * + * @param label The view that labels this node's source. + */ + public void setLabeledBy(View label) { + setLabeledBy(label, UNDEFINED); + } + + /** + * Sets the view which serves as the label of the view represented by + * this info for accessibility purposes. If <code>virtualDescendantId</code> + * is {@link View#NO_ID} the root is set as the label. + * <p> + * A virtual descendant is an imaginary View that is reported as a part of the view + * hierarchy for accessibility purposes. This enables custom views that draw complex + * content to report themselves as a tree of virtual views, thus conveying their + * logical structure. + * </p> + * <p> + * <strong>Note:</strong> Cannot be called from an + * {@link android.accessibilityservice.AccessibilityService}. + * This class is made immutable before being delivered to an AccessibilityService. + * </p> + * + * @param root The root whose virtual descendant labels this node's source. + * @param virtualDescendantId The id of the virtual descendant. + */ + public void setLabeledBy(View root, int virtualDescendantId) { + enforceNotSealed(); + final int rootAccessibilityViewId = (root != null) + ? root.getAccessibilityViewId() : UNDEFINED; + mLabeledById = makeNodeId(rootAccessibilityViewId, virtualDescendantId); + } + + /** + * Gets the node info which serves as the label of the view represented by + * this info for accessibility purposes. + * <p> + * <strong>Note:</strong> It is a client responsibility to recycle the + * received info by calling {@link AccessibilityNodeInfo#recycle()} + * to avoid creating of multiple instances. + * </p> + * + * @return The label. + */ + public AccessibilityNodeInfo getLabeledBy() { + enforceSealed(); + if (!canPerformRequestOverConnection(mLabeledById)) { + return null; + } + AccessibilityInteractionClient client = AccessibilityInteractionClient.getInstance(); + return client.findAccessibilityNodeInfoByAccessibilityId(mConnectionId, + mWindowId, mLabeledById, FLAG_PREFETCH_DESCENDANTS | FLAG_PREFETCH_SIBLINGS); + } + + /** * Gets the value of a boolean property. * * @param property The property. @@ -1462,6 +1578,8 @@ public class AccessibilityNodeInfo implements Parcelable { parcel.writeLong(mSourceNodeId); parcel.writeInt(mWindowId); parcel.writeLong(mParentNodeId); + parcel.writeLong(mLabelForId); + parcel.writeLong(mLabeledById); parcel.writeInt(mConnectionId); SparseLongArray childIds = mChildNodeIds; @@ -1507,6 +1625,8 @@ public class AccessibilityNodeInfo implements Parcelable { mSealed = other.mSealed; mSourceNodeId = other.mSourceNodeId; mParentNodeId = other.mParentNodeId; + mLabelForId = other.mLabelForId; + mLabeledById = other.mLabeledById; mWindowId = other.mWindowId; mConnectionId = other.mConnectionId; mBoundsInParent.set(other.mBoundsInParent); @@ -1534,6 +1654,8 @@ public class AccessibilityNodeInfo implements Parcelable { mSourceNodeId = parcel.readLong(); mWindowId = parcel.readInt(); mParentNodeId = parcel.readLong(); + mLabelForId = parcel.readLong(); + mLabeledById = parcel.readLong(); mConnectionId = parcel.readInt(); SparseLongArray childIds = mChildNodeIds; @@ -1572,6 +1694,8 @@ public class AccessibilityNodeInfo implements Parcelable { mSealed = false; mSourceNodeId = ROOT_NODE_ID; mParentNodeId = ROOT_NODE_ID; + mLabelForId = ROOT_NODE_ID; + mLabeledById = ROOT_NODE_ID; mWindowId = UNDEFINED; mConnectionId = UNDEFINED; mMovementGranularities = 0; diff --git a/core/java/android/webkit/CacheManager.java b/core/java/android/webkit/CacheManager.java index f0e6ff0..52f41e6 100644 --- a/core/java/android/webkit/CacheManager.java +++ b/core/java/android/webkit/CacheManager.java @@ -32,6 +32,7 @@ import java.util.Map; /** * Manages the HTTP cache used by an application's {@link WebView} instances. * @deprecated Access to the HTTP cache will be removed in a future release. + * @hide Since {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR1} */ // The class CacheManager provides the persistent cache of content that is // received over the network. The component handles parsing of HTTP headers and diff --git a/core/java/android/webkit/DateSorter.java b/core/java/android/webkit/DateSorter.java index 0e8ad7e..82c13ae 100644 --- a/core/java/android/webkit/DateSorter.java +++ b/core/java/android/webkit/DateSorter.java @@ -21,6 +21,9 @@ import android.content.res.Resources; import java.util.Calendar; import java.util.Date; +import java.util.Locale; + +import libcore.icu.LocaleData; /** * Sorts dates into the following groups: @@ -63,8 +66,13 @@ public class DateSorter { mBins[3] = c.getTimeInMillis(); // One month ago // build labels - mLabels[0] = context.getText(com.android.internal.R.string.today).toString(); - mLabels[1] = context.getText(com.android.internal.R.string.yesterday).toString(); + Locale locale = resources.getConfiguration().locale; + if (locale == null) { + locale = Locale.getDefault(); + } + LocaleData localeData = LocaleData.get(locale); + mLabels[0] = localeData.today; + mLabels[1] = localeData.yesterday; int resId = com.android.internal.R.plurals.last_num_days; String format = resources.getQuantityString(resId, NUM_DAYS_AGO); diff --git a/core/java/android/webkit/WebHistoryItem.java b/core/java/android/webkit/WebHistoryItem.java index cc9afe0..9a588e4 100644 --- a/core/java/android/webkit/WebHistoryItem.java +++ b/core/java/android/webkit/WebHistoryItem.java @@ -38,6 +38,7 @@ public class WebHistoryItem implements Cloneable { * same object. * @return The id for this item. * @deprecated This method is now obsolete. + * @hide Since API level {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR1} */ @Deprecated public int getId() { diff --git a/core/java/android/webkit/WebSettings.java b/core/java/android/webkit/WebSettings.java index a29ff37..be2d863 100644 --- a/core/java/android/webkit/WebSettings.java +++ b/core/java/android/webkit/WebSettings.java @@ -164,6 +164,7 @@ public abstract class WebSettings { * is false. * * @deprecated This method is now obsolete. + * @hide Since API level {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR1} */ @Deprecated public void setNavDump(boolean enabled) { @@ -176,6 +177,7 @@ public abstract class WebSettings { * @return whether dumping the navigation cache is enabled * @see #setNavDump * @deprecated This method is now obsolete. + * @hide Since API level {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR1} */ @Deprecated public boolean getNavDump() { @@ -377,6 +379,7 @@ public abstract class WebSettings { * * @see #setUseWebViewBackgroundForOverscrollBackground * @deprecated This method is now obsolete. + * @hide Since API level {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR1} */ @Deprecated public boolean getUseWebViewBackgroundForOverscrollBackground() { @@ -518,6 +521,7 @@ public abstract class WebSettings { * it now has no effect. * * @deprecated This setting now has no effect. + * @hide Since API level {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR1} */ @Deprecated public synchronized void setUseDoubleTree(boolean use) { @@ -529,6 +533,7 @@ public abstract class WebSettings { * it now has no effect. * * @deprecated This setting now has no effect. + * @hide Since API level {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR1} */ @Deprecated public synchronized boolean getUseDoubleTree() { @@ -547,6 +552,7 @@ public abstract class WebSettings { * * @param ua the integer code for the user-agent string * @deprecated Please use {@link #setUserAgentString} instead. + * @hide Since API level {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR1} */ @Deprecated public synchronized void setUserAgent(int ua) { @@ -565,6 +571,7 @@ public abstract class WebSettings { * @return the integer code for the user-agent string * @see #setUserAgent * @deprecated Please use {@link #getUserAgentString} instead. + * @hide Since API level {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR1} */ @Deprecated public synchronized int getUserAgent() { @@ -1251,8 +1258,7 @@ public abstract class WebSettings { /** * Returns the default User-Agent used by a WebView. * An instance of WebView could use a different User-Agent if a call - * is made to {@link WebSettings#setUserAgent(int)} or - * {@link WebSettings#setUserAgentString(String)}. + * is made to {@link WebSettings#setUserAgentString(String)}. * * @param context a Context object used to access application assets */ diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java index e1c30f7..4202a7f 100644 --- a/core/java/android/webkit/WebView.java +++ b/core/java/android/webkit/WebView.java @@ -555,6 +555,7 @@ public class WebView extends AbsoluteLayout * Gets the visible height (in pixels) of the embedded title bar (if any). * * @deprecated This method is now obsolete. + * @hide Since API level {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR1} */ public int getVisibleTitleHeight() { checkThread(); @@ -658,6 +659,7 @@ public class WebView extends AbsoluteLayout * Notifications are enabled by default. * * @deprecated This method is now obsolete. + * @hide Since API level {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR1} */ @Deprecated public static void enablePlatformNotifications() { @@ -670,6 +672,7 @@ public class WebView extends AbsoluteLayout * Notifications are enabled by default. * * @deprecated This method is now obsolete. + * @hide Since API level {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR1} */ @Deprecated public static void disablePlatformNotifications() { @@ -694,14 +697,11 @@ public class WebView extends AbsoluteLayout * {@link android.app.Activity#onSaveInstanceState}. Please note that this * method no longer stores the display data for this WebView. The previous * behavior could potentially leak files if {@link #restoreState} was never - * called. See {@link #savePicture} and {@link #restorePicture} for saving - * and restoring the display data. + * called. * * @param outState the Bundle to store this WebView's state * @return the same copy of the back/forward list used to save the state. If * saveState fails, the returned list will be null. - * @see #savePicture - * @see #restorePicture */ public WebBackForwardList saveState(Bundle outState) { checkThread(); @@ -716,6 +716,7 @@ public class WebView extends AbsoluteLayout * overwritten with this WebView's picture data. * @return true if the picture was successfully saved * @deprecated This method is now obsolete. + * @hide Since API level {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR1} */ @Deprecated public boolean savePicture(Bundle b, final File dest) { @@ -732,6 +733,7 @@ public class WebView extends AbsoluteLayout * @param src the file where the picture data was stored * @return true if the picture was successfully restored * @deprecated This method is now obsolete. + * @hide Since API level {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR1} */ @Deprecated public boolean restorePicture(Bundle b, File src) { @@ -746,13 +748,10 @@ public class WebView extends AbsoluteLayout * it is called after this WebView has had a chance to build state (load * pages, create a back/forward list, etc.) there may be undesirable * side-effects. Please note that this method no longer restores the - * display data for this WebView. See {@link #savePicture} and {@link - * #restorePicture} for saving and restoring the display data. + * display data for this WebView. * * @param inState the incoming Bundle of state * @return the restored back/forward list or null if restoreState failed - * @see #savePicture - * @see #restorePicture */ public WebBackForwardList restoreState(Bundle inState) { checkThread(); @@ -1334,12 +1333,11 @@ public class WebView extends AbsoluteLayout } /** - * Highlights and scrolls to the next match found by {@link #findAll} or + * Highlights and scrolls to the next match found by * {@link #findAllAsync}, wrapping around page boundaries as necessary. - * Notifies any registered {@link FindListener}. If neither - * {@link #findAll} nor {@link #findAllAsync(String)} has been called yet, - * or if {@link #clearMatches} has been called since the last find - * operation, this function does nothing. + * Notifies any registered {@link FindListener}. If {@link #findAllAsync(String)} + * has not been called yet, or if {@link #clearMatches} has been called since the + * last find operation, this function does nothing. * * @param forward the direction to search * @see #setFindListener @@ -1368,8 +1366,7 @@ public class WebView extends AbsoluteLayout /** * Finds all instances of find on the page and highlights them, * asynchronously. Notifies any registered {@link FindListener}. - * Successive calls to this or {@link #findAll} will cancel any - * pending searches. + * Successive calls to this will cancel any pending searches. * * @param find the string to find. * @see #setFindListener @@ -1423,7 +1420,7 @@ public class WebView extends AbsoluteLayout /** * Clears the highlighting surrounding text matches created by - * {@link #findAll} or {@link #findAllAsync}. + * {@link #findAllAsync}. */ public void clearMatches() { checkThread(); @@ -1483,6 +1480,7 @@ public class WebView extends AbsoluteLayout * * @param listener an implementation of WebView.PictureListener * @deprecated This method is now obsolete. + * @hide Since API level {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR1} */ @Deprecated public void setPictureListener(PictureListener listener) { @@ -1590,6 +1588,7 @@ public class WebView extends AbsoluteLayout * functionality; it will be deprecated in the future. * * @deprecated This method is now obsolete. + * @hide Since API level {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR1} */ @Deprecated public void emulateShiftHeld() { @@ -1709,6 +1708,7 @@ public class WebView extends AbsoluteLayout /** * @deprecated This method is now obsolete. + * @hide Since API level {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR1} */ @Deprecated public void debugDump() { diff --git a/core/java/android/webkit/WebViewDatabase.java b/core/java/android/webkit/WebViewDatabase.java index 1987f53..62ec0d5 100644 --- a/core/java/android/webkit/WebViewDatabase.java +++ b/core/java/android/webkit/WebViewDatabase.java @@ -29,7 +29,9 @@ import android.content.Context; * </ul> */ public class WebViewDatabase { - // TODO: deprecate/hide this. + /** + * @hide Since API level {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR1} + */ protected static final String LOGTAG = "webviewdatabase"; /** diff --git a/core/java/android/widget/RemoteViews.java b/core/java/android/widget/RemoteViews.java index dcf90e9..c65a67b 100644 --- a/core/java/android/widget/RemoteViews.java +++ b/core/java/android/widget/RemoteViews.java @@ -2077,15 +2077,25 @@ public class RemoteViews implements Parcelable, Filter { } /** - * Equivalent to calling View.setContentDescription + * Equivalent to calling View.setContentDescription(CharSequence). * - * @param viewId The id of the view whose content description should change - * @param contentDescription The new content description for the view + * @param viewId The id of the view whose content description should change. + * @param contentDescription The new content description for the view. */ public void setContentDescription(int viewId, CharSequence contentDescription) { setCharSequence(viewId, "setContentDescription", contentDescription); } + /** + * Equivalent to calling View.setLabelFor(int). + * + * @param viewId The id of the view whose property to set. + * @param labeledId The id of a view for which this view serves as a label. + */ + public void setLabelFor(int viewId, int labeledId) { + setInt(viewId, "setLabelFor", labeledId); + } + private RemoteViews getRemoteViewsToApply(Context context) { if (hasLandscapeAndPortraitLayouts()) { int orientation = context.getResources().getConfiguration().orientation; diff --git a/core/java/android/widget/Switch.java b/core/java/android/widget/Switch.java index 689bd02..e754c17 100644 --- a/core/java/android/widget/Switch.java +++ b/core/java/android/widget/Switch.java @@ -508,9 +508,9 @@ public class Switch extends CompoundButton { @Override public void onPopulateAccessibilityEvent(AccessibilityEvent event) { super.onPopulateAccessibilityEvent(event); - CharSequence text = isChecked() ? mOnLayout.getText() : mOffLayout.getText(); - if (!TextUtils.isEmpty(text)) { - event.getText().add(text); + Layout layout = isChecked() ? mOnLayout : mOffLayout; + if (layout != null && !TextUtils.isEmpty(layout.getText())) { + event.getText().add(layout.getText()); } } diff --git a/core/java/com/android/internal/widget/LockPatternUtils.java b/core/java/com/android/internal/widget/LockPatternUtils.java index 4777c16..0710d96 100644 --- a/core/java/com/android/internal/widget/LockPatternUtils.java +++ b/core/java/com/android/internal/widget/LockPatternUtils.java @@ -20,6 +20,7 @@ import com.android.internal.R; import com.android.internal.telephony.ITelephony; import com.google.android.collect.Lists; +import android.app.ActivityManagerNative; import android.app.admin.DevicePolicyManager; import android.content.BroadcastReceiver; import android.content.ContentResolver; @@ -225,7 +226,11 @@ public class LockPatternUtils { public int getCurrentUser() { if (Process.myUid() == Process.SYSTEM_UID) { - return mCurrentUserId; + try { + return ActivityManagerNative.getDefault().getCurrentUser().id; + } catch (RemoteException re) { + return mCurrentUserId; + } } else { throw new SecurityException("Only the system process can get the current user"); } @@ -1001,6 +1006,17 @@ public class LockPatternUtils { } } + public int[] getUserDefinedWidgets() { + int appWidgetId = -1; + String appWidgetIdString = Settings.Secure.getString( + mContentResolver, Settings.Secure.LOCK_SCREEN_USER_SELECTED_APPWIDGET_ID); + if (appWidgetIdString != null) { + appWidgetId = (int) Integer.decode(appWidgetIdString); + } + + return new int[] { appWidgetId }; + } + private long getLong(String secureSettingKey, long defaultValue) { try { return getLockSettings().getLong(secureSettingKey, defaultValue, |
