diff options
Diffstat (limited to 'core/java/android')
28 files changed, 382 insertions, 288 deletions
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java index e8ab109..9c2e208 100644 --- a/core/java/android/app/Activity.java +++ b/core/java/android/app/Activity.java @@ -6473,20 +6473,22 @@ public class Activity extends ContextThemeWrapper } private void dispatchRequestPermissionsResult(int requestCode, Intent data) { - String[] permissions = data.getStringArrayExtra( - PackageManager.EXTRA_REQUEST_PERMISSIONS_NAMES); - final int[] grantResults = data.getIntArrayExtra( - PackageManager.EXTRA_REQUEST_PERMISSIONS_RESULTS); + // If the package installer crashed we may have not data - best effort. + String[] permissions = (data != null) ? data.getStringArrayExtra( + PackageManager.EXTRA_REQUEST_PERMISSIONS_NAMES) : new String[0]; + final int[] grantResults = (data != null) ? data.getIntArrayExtra( + PackageManager.EXTRA_REQUEST_PERMISSIONS_RESULTS) : new int[0]; onRequestPermissionsResult(requestCode, permissions, grantResults); } private void dispatchRequestPermissionsResultToFragment(int requestCode, Intent data, - Fragment fragement) { - String[] permissions = data.getStringArrayExtra( - PackageManager.EXTRA_REQUEST_PERMISSIONS_NAMES); - final int[] grantResults = data.getIntArrayExtra( - PackageManager.EXTRA_REQUEST_PERMISSIONS_RESULTS); - fragement.onRequestPermissionsResult(requestCode, permissions, grantResults); + Fragment fragment) { + // If the package installer crashed we may have not data - best effort. + String[] permissions = (data != null) ? data.getStringArrayExtra( + PackageManager.EXTRA_REQUEST_PERMISSIONS_NAMES) : new String[0]; + final int[] grantResults = (data != null) ? data.getIntArrayExtra( + PackageManager.EXTRA_REQUEST_PERMISSIONS_RESULTS) : new int[0]; + fragment.onRequestPermissionsResult(requestCode, permissions, grantResults); } class HostCallbacks extends FragmentHostCallback<Activity> { diff --git a/core/java/android/app/AppOpsManager.java b/core/java/android/app/AppOpsManager.java index 8a61ec6..9faadd3 100644 --- a/core/java/android/app/AppOpsManager.java +++ b/core/java/android/app/AppOpsManager.java @@ -229,8 +229,12 @@ public class AppOpsManager { public static final int OP_READ_CELL_BROADCASTS = 57; /** @hide Inject mock location into the system. */ public static final int OP_MOCK_LOCATION = 58; + /** @hide Read external storage. */ + public static final int OP_READ_EXTERNAL_STORAGE = 59; + /** @hide Write external storage. */ + public static final int OP_WRITE_EXTERNAL_STORAGE = 60; /** @hide */ - public static final int _NUM_OP = 59; + public static final int _NUM_OP = 61; /** Access to coarse location information. */ public static final String OPSTR_COARSE_LOCATION = "android:coarse_location"; @@ -313,6 +317,12 @@ public class AppOpsManager { /** Inject mock location into the system. */ public static final String OPSTR_MOCK_LOCATION = "android:mock_location"; + /** Read external storage. */ + public static final String OPSTR_READ_EXTERNAL_STORAGE + = "android:read_external_storage"; + /** Write external storage. */ + public static final String OPSTR_WRITE_EXTERNAL_STORAGE + = "android:write_external_storage"; /** * This maps each operation to the operation that serves as the @@ -381,7 +391,9 @@ public class AppOpsManager { OP_USE_FINGERPRINT, OP_BODY_SENSORS, OP_READ_CELL_BROADCASTS, - OP_MOCK_LOCATION + OP_MOCK_LOCATION, + OP_READ_EXTERNAL_STORAGE, + OP_WRITE_EXTERNAL_STORAGE }; /** @@ -447,7 +459,9 @@ public class AppOpsManager { OPSTR_USE_FINGERPRINT, OPSTR_BODY_SENSORS, OPSTR_READ_CELL_BROADCASTS, - OPSTR_MOCK_LOCATION + OPSTR_MOCK_LOCATION, + OPSTR_READ_EXTERNAL_STORAGE, + OPSTR_WRITE_EXTERNAL_STORAGE }; /** @@ -513,7 +527,9 @@ public class AppOpsManager { "USE_FINGERPRINT", "BODY_SENSORS", "READ_CELL_BROADCASTS", - "MOCK_LOCATION" + "MOCK_LOCATION", + "OPSTR_READ_EXTERNAL_STORAGE", + "OPSTR_WRITE_EXTERNAL_STORAGE", }; /** @@ -579,7 +595,9 @@ public class AppOpsManager { Manifest.permission.USE_FINGERPRINT, Manifest.permission.BODY_SENSORS, Manifest.permission.READ_CELL_BROADCASTS, - null + null, + Manifest.permission.READ_EXTERNAL_STORAGE, + Manifest.permission.WRITE_EXTERNAL_STORAGE, }; /** @@ -646,7 +664,9 @@ public class AppOpsManager { null, // USE_FINGERPRINT null, // BODY_SENSORS null, // READ_CELL_BROADCASTS - null // MOCK_LOCATION + null, // MOCK_LOCATION + null, // READ_EXTERNAL_STORAGE + null // WRITE_EXTERNAL_STORAGE }; /** @@ -712,7 +732,9 @@ public class AppOpsManager { false, // USE_FINGERPRINT false, // BODY_SENSORS false, // READ_CELL_BROADCASTS - false // MOCK_LOCATION + false, // MOCK_LOCATION + false, // READ_EXTERNAL_STORAGE + false // WRITE_EXTERNAL_STORAGE }; /** @@ -777,7 +799,9 @@ public class AppOpsManager { AppOpsManager.MODE_ALLOWED, AppOpsManager.MODE_ALLOWED, AppOpsManager.MODE_ALLOWED, - AppOpsManager.MODE_ERRORED // OP_MOCK_LOCATION + AppOpsManager.MODE_ERRORED, // OP_MOCK_LOCATION + AppOpsManager.MODE_ALLOWED, + AppOpsManager.MODE_ALLOWED }; /** @@ -846,6 +870,8 @@ public class AppOpsManager { false, false, false, + false, + false, false }; diff --git a/core/java/android/app/BackStackRecord.java b/core/java/android/app/BackStackRecord.java index 903411e..13030ca 100644 --- a/core/java/android/app/BackStackRecord.java +++ b/core/java/android/app/BackStackRecord.java @@ -717,6 +717,7 @@ final class BackStackRecord extends FragmentTransaction implements break; case OP_REPLACE: { Fragment f = op.fragment; + int containerId = f.mContainerId; if (mManager.mAdded != null) { for (int i = 0; i < mManager.mAdded.size(); i++) { Fragment old = mManager.mAdded.get(i); @@ -724,7 +725,7 @@ final class BackStackRecord extends FragmentTransaction implements Log.v(TAG, "OP_REPLACE: adding=" + f + " old=" + old); } - if (f == null || old.mContainerId == f.mContainerId) { + if (old.mContainerId == containerId) { if (old == f) { op.fragment = f = null; } else { diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java index d53157b..d28ff51 100644 --- a/core/java/android/app/admin/DevicePolicyManager.java +++ b/core/java/android/app/admin/DevicePolicyManager.java @@ -3612,7 +3612,10 @@ public class DevicePolicyManager { * @see UserHandle * @return the {@link android.os.UserHandle} object for the created user, or {@code null} if the * user could not be created. + * + * @deprecated From {@link android.os.Build.VERSION_CODES#MNC} */ + @Deprecated public UserHandle createUser(@NonNull ComponentName admin, String name) { try { return mService.createUser(admin, name); @@ -3646,7 +3649,10 @@ public class DevicePolicyManager { * @see UserHandle * @return the {@link android.os.UserHandle} object for the created user, or {@code null} if the * user could not be created. + * + * @deprecated From {@link android.os.Build.VERSION_CODES#MNC} */ + @Deprecated public UserHandle createAndInitializeUser(@NonNull ComponentName admin, String name, String ownerName, @NonNull ComponentName profileOwnerComponent, Bundle adminExtras) { try { @@ -3962,24 +3968,27 @@ public class DevicePolicyManager { * <li>{@link Settings.Global#ADB_ENABLED}</li> * <li>{@link Settings.Global#AUTO_TIME}</li> * <li>{@link Settings.Global#AUTO_TIME_ZONE}</li> - * <li>{@link Settings.Global#BLUETOOTH_ON} - * Changing this setting has not effect as of {@link android.os.Build.VERSION_CODES#MNC}. Use - * {@link android.bluetooth.BluetoothAdapter#enable()} and - * {@link android.bluetooth.BluetoothAdapter#disable()} instead.</li> * <li>{@link Settings.Global#DATA_ROAMING}</li> - * <li>{@link Settings.Global#DEVELOPMENT_SETTINGS_ENABLED}</li> - * <li>{@link Settings.Global#MODE_RINGER}</li> - * <li>{@link Settings.Global#NETWORK_PREFERENCE}</li> * <li>{@link Settings.Global#USB_MASS_STORAGE_ENABLED}</li> - * <li>{@link Settings.Global#WIFI_ON} - * Changing this setting has not effect as of {@link android.os.Build.VERSION_CODES#MNC}. Use - * {@link android.net.wifi.WifiManager#setWifiEnabled(boolean)} instead.</li> * <li>{@link Settings.Global#WIFI_SLEEP_POLICY}</li> * <li>{@link Settings.Global#STAY_ON_WHILE_PLUGGED_IN} - * This setting is only available from {@link android.os.Build.VERSION_CODES#MNC} onwards - * and can only be set if {@link #setMaximumTimeToLock} is not used to set a timeout.</li> + * This setting is only available from {@link android.os.Build.VERSION_CODES#MNC} onwards + * and can only be set if {@link #setMaximumTimeToLock} is not used to set a timeout.</li> * <li>{@link Settings.Global#WIFI_DEVICE_OWNER_CONFIGS_LOCKDOWN}</li> * </ul> + * <p>Changing the following settings has no effect as of + * {@link android.os.Build.VERSION_CODES#MNC}: + * <ul> + * <li>{@link Settings.Global#BLUETOOTH_ON}. + * Use {@link android.bluetooth.BluetoothAdapter#enable()} and + * {@link android.bluetooth.BluetoothAdapter#disable()} instead.</li> + * <li>{@link Settings.Global#DEVELOPMENT_SETTINGS_ENABLED}</li> + * <li>{@link Settings.Global#MODE_RINGER}. + * Use {@link android.media.AudioManager#setRingerMode(int)} instead.</li> + * <li>{@link Settings.Global#NETWORK_PREFERENCE}</li> + * <li>{@link Settings.Global#WIFI_ON}. + * Use {@link android.net.wifi.WifiManager#setWifiEnabled(boolean)} instead.</li> + * </ul> * * @param admin Which {@link DeviceAdminReceiver} this request is associated with. * @param setting The name of the setting to update. diff --git a/core/java/android/app/assist/AssistContent.java b/core/java/android/app/assist/AssistContent.java index 07b2d57..cddf47a 100644 --- a/core/java/android/app/assist/AssistContent.java +++ b/core/java/android/app/assist/AssistContent.java @@ -12,7 +12,6 @@ import android.os.Parcelable; * assistant at the user's request. This is filled in by * {@link android.app.Activity#onProvideAssistContent Activity.onProvideAssistContent}. */ -@Deprecated public class AssistContent implements Parcelable { private boolean mIsAppProvidedIntent = false; private Intent mIntent; diff --git a/core/java/android/app/usage/UsageEvents.java b/core/java/android/app/usage/UsageEvents.java index 369b692..24647f3 100644 --- a/core/java/android/app/usage/UsageEvents.java +++ b/core/java/android/app/usage/UsageEvents.java @@ -372,13 +372,4 @@ public final class UsageEvents implements Parcelable { return new UsageEvents[size]; } }; - - @Override - protected void finalize() throws Throwable { - super.finalize(); - if (mParcel != null) { - mParcel.recycle(); - mParcel = null; - } - } } diff --git a/core/java/android/content/ContentResolver.java b/core/java/android/content/ContentResolver.java index d37dda0..6ede29b 100644 --- a/core/java/android/content/ContentResolver.java +++ b/core/java/android/content/ContentResolver.java @@ -1593,7 +1593,11 @@ public abstract class ContentResolver { @NonNull ContentObserver observer) { Preconditions.checkNotNull(uri, "uri"); Preconditions.checkNotNull(observer, "observer"); - registerContentObserver(uri, notifyForDescendents, observer, UserHandle.myUserId()); + registerContentObserver( + ContentProvider.getUriWithoutUserId(uri), + notifyForDescendents, + observer, + ContentProvider.getUserIdFromUri(uri, UserHandle.myUserId())); } /** @hide - designated user version */ @@ -1659,7 +1663,11 @@ public abstract class ContentResolver { public void notifyChange(@NonNull Uri uri, @Nullable ContentObserver observer, boolean syncToNetwork) { Preconditions.checkNotNull(uri, "uri"); - notifyChange(uri, observer, syncToNetwork, UserHandle.myUserId()); + notifyChange( + ContentProvider.getUriWithoutUserId(uri), + observer, + syncToNetwork, + ContentProvider.getUserIdFromUri(uri, UserHandle.myUserId())); } /** diff --git a/core/java/android/content/pm/IPackageManager.aidl b/core/java/android/content/pm/IPackageManager.aidl index cea6e99..2b83d86 100644 --- a/core/java/android/content/pm/IPackageManager.aidl +++ b/core/java/android/content/pm/IPackageManager.aidl @@ -31,7 +31,6 @@ import android.content.pm.IPackageDeleteObserver2; import android.content.pm.IPackageDataObserver; import android.content.pm.IPackageMoveObserver; import android.content.pm.IPackageStatsObserver; -import android.content.pm.IPackagesProvider; import android.content.pm.IOnPermissionsChangeListener; import android.content.pm.IntentFilterVerificationInfo; import android.content.pm.InstrumentationInfo; @@ -504,7 +503,7 @@ interface IPackageManager { void addOnPermissionsChangeListener(in IOnPermissionsChangeListener listener); void removeOnPermissionsChangeListener(in IOnPermissionsChangeListener listener); - void grantDefaultPermissions(int userId); - void setCarrierAppPackagesProvider(in IPackagesProvider provider); int getMountExternalMode(int uid); + + void grantDefaultPermissionsToEnabledCarrierApps(in String[] packageNames, int userId); } diff --git a/core/java/android/content/pm/IPackagesProvider.aidl b/core/java/android/content/pm/IPackagesProvider.aidl deleted file mode 100644 index 7d76c88..0000000 --- a/core/java/android/content/pm/IPackagesProvider.aidl +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright (C) 2015 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.content.pm; - -/** {@hide} */ -interface IPackagesProvider { - String[] getPackages(int userId); -} diff --git a/core/java/android/content/pm/PackageManagerInternal.java b/core/java/android/content/pm/PackageManagerInternal.java index 7599bd6..dbaba49 100644 --- a/core/java/android/content/pm/PackageManagerInternal.java +++ b/core/java/android/content/pm/PackageManagerInternal.java @@ -55,4 +55,30 @@ public abstract class PackageManagerInternal { * @param provider The packages provider. */ public abstract void setVoiceInteractionPackagesProvider(PackagesProvider provider); + + /** + * Sets the SMS packages provider. + * @param provider The packages provider. + */ + public abstract void setSmsAppPackagesProvider(PackagesProvider provider); + + /** + * Sets the dialer packages provider. + * @param provider The packages provider. + */ + public abstract void setDialerAppPackagesProvider(PackagesProvider provider); + + /** + * Requests granting of the default permissions to the current default SMS app. + * @param packageName The default SMS package name. + * @param userId The user for which to grant the permissions. + */ + public abstract void grantDefaultPermissionsToDefaultSmsApp(String packageName, int userId); + + /** + * Requests granting of the default permissions to the current default dialer app. + * @param packageName The default dialer package name. + * @param userId The user for which to grant the permissions. + */ + public abstract void grantDefaultPermissionsToDefaultDialerApp(String packageName, int userId); } diff --git a/core/java/android/net/LinkProperties.java b/core/java/android/net/LinkProperties.java index 31aedad..cfd5bf1 100644 --- a/core/java/android/net/LinkProperties.java +++ b/core/java/android/net/LinkProperties.java @@ -517,7 +517,7 @@ public final class LinkProperties implements Parcelable { * Note that Http Proxies are only a hint - the system recommends their use, but it does * not enforce it and applications may ignore them. * - * @param proxy A {@link ProxyInfo} defining the Http Proxy to use on this link. + * @param proxy A {@link ProxyInfo} defining the HTTP Proxy to use on this link. * @hide */ public void setHttpProxy(ProxyInfo proxy) { @@ -774,6 +774,43 @@ public final class LinkProperties implements Parcelable { } /** + * Evaluate whether the {@link InetAddress} is considered reachable. + * + * @return {@code true} if the given {@link InetAddress} is considered reachable, + * {@code false} otherwise. + * @hide + */ + public boolean isReachable(InetAddress ip) { + final List<RouteInfo> allRoutes = getAllRoutes(); + // If we don't have a route to this IP address, it's not reachable. + final RouteInfo bestRoute = RouteInfo.selectBestRoute(allRoutes, ip); + if (bestRoute == null) { + return false; + } + + // TODO: better source address evaluation for destination addresses. + + if (ip instanceof Inet4Address) { + // For IPv4, it suffices for now to simply have any address. + return hasIPv4Address(); + } else if (ip instanceof Inet6Address) { + if (ip.isLinkLocalAddress()) { + // For now, just make sure link-local destinations have + // scopedIds set, since transmits will generally fail otherwise. + // TODO: verify it matches the ifindex of one of the interfaces. + return (((Inet6Address)ip).getScopeId() != 0); + } else { + // For non-link-local destinations check that either the best route + // is directly connected or that some global preferred address exists. + // TODO: reconsider all cases (disconnected ULA networks, ...). + return (!bestRoute.hasGateway() || hasGlobalIPv6Address()); + } + } + + return false; + } + + /** * Compares this {@code LinkProperties} interface name against the target * * @param target LinkProperties to compare. diff --git a/core/java/android/os/BatteryStats.java b/core/java/android/os/BatteryStats.java index 7fda30a..fe323f3 100644 --- a/core/java/android/os/BatteryStats.java +++ b/core/java/android/os/BatteryStats.java @@ -184,6 +184,7 @@ public abstract class BatteryStats implements Parcelable { private static final String UID_DATA = "uid"; private static final String APK_DATA = "apk"; private static final String PROCESS_DATA = "pr"; + private static final String CPU_DATA = "cpu"; private static final String SENSOR_DATA = "sr"; private static final String VIBRATOR_DATA = "vib"; private static final String FOREGROUND_DATA = "fg"; @@ -457,8 +458,13 @@ public abstract class BatteryStats implements Parcelable { public abstract long getSystemCpuTimeUs(int which); /** + * Get the total cpu power consumed (in milli-ampere-microseconds). + */ + public abstract long getCpuPowerMaUs(int which); + + /** * Returns the approximate cpu time (in milliseconds) spent at a certain CPU speed. - * @param speedStep the index of the CPU speed. This is not the actual speed of the CPU. + * @param step the index of the CPU speed. This is not the actual speed of the CPU. * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT. * @see BatteryStats#getCpuSpeedSteps() */ @@ -2905,6 +2911,14 @@ public abstract class BatteryStats implements Parcelable { dumpLine(pw, uid, category, STATE_TIME_DATA, stateTimes); } + final long userCpuTimeUs = u.getUserCpuTimeUs(which); + final long systemCpuTimeUs = u.getSystemCpuTimeUs(which); + final long powerCpuMaUs = u.getCpuPowerMaUs(which); + if (userCpuTimeUs > 0 || systemCpuTimeUs > 0 || powerCpuMaUs > 0) { + dumpLine(pw, uid, category, CPU_DATA, userCpuTimeUs / 1000, systemCpuTimeUs / 1000, + powerCpuMaUs / 1000); + } + final ArrayMap<String, ? extends BatteryStats.Uid.Proc> processStats = u.getProcessStats(); for (int ipr=processStats.size()-1; ipr>=0; ipr--) { @@ -2970,6 +2984,10 @@ public abstract class BatteryStats implements Parcelable { printer.print(BatteryStatsHelper.makemAh(power)); } + private void printmAh(StringBuilder sb, double power) { + sb.append(BatteryStatsHelper.makemAh(power)); + } + /** * Temporary for settings. */ @@ -4028,13 +4046,17 @@ public abstract class BatteryStats implements Parcelable { final long userCpuTimeUs = u.getUserCpuTimeUs(which); final long systemCpuTimeUs = u.getSystemCpuTimeUs(which); - if (userCpuTimeUs > 0 || systemCpuTimeUs > 0) { + final long powerCpuMaUs = u.getCpuPowerMaUs(which); + if (userCpuTimeUs > 0 || systemCpuTimeUs > 0 || powerCpuMaUs > 0) { sb.setLength(0); sb.append(prefix); sb.append(" Total cpu time: u="); formatTimeMs(sb, userCpuTimeUs / 1000); sb.append("s="); formatTimeMs(sb, systemCpuTimeUs / 1000); + sb.append("p="); + printmAh(sb, powerCpuMaUs / (1000.0 * 1000.0 * 60.0 * 60.0)); + sb.append("mAh"); pw.println(sb.toString()); } diff --git a/core/java/android/os/DeadObjectException.java b/core/java/android/os/DeadObjectException.java index 94c5387..e06b0f9 100644 --- a/core/java/android/os/DeadObjectException.java +++ b/core/java/android/os/DeadObjectException.java @@ -25,4 +25,8 @@ public class DeadObjectException extends RemoteException { public DeadObjectException() { super(); } + + public DeadObjectException(String message) { + super(message); + } } diff --git a/core/java/android/os/UserHandle.java b/core/java/android/os/UserHandle.java index 6874e77..511bd5f 100644 --- a/core/java/android/os/UserHandle.java +++ b/core/java/android/os/UserHandle.java @@ -179,6 +179,19 @@ public final class UserHandle implements Parcelable { } /** + * Returns the app id for a given shared app gid. + * @hide + */ + public static final int getAppIdFromSharedAppGid(int gid) { + final int noUserGid = getAppId(gid); + if (noUserGid < Process.FIRST_SHARED_APPLICATION_GID || + noUserGid > Process.LAST_SHARED_APPLICATION_GID) { + throw new IllegalArgumentException(Integer.toString(gid) + " is not a shared app gid"); + } + return (noUserGid + Process.FIRST_APPLICATION_UID) - Process.FIRST_SHARED_APPLICATION_GID; + } + + /** * Generate a text representation of the uid, breaking out its individual * components -- user, app, isolated, etc. * @hide diff --git a/core/java/android/os/UserManager.java b/core/java/android/os/UserManager.java index 9770941..b104135 100644 --- a/core/java/android/os/UserManager.java +++ b/core/java/android/os/UserManager.java @@ -449,6 +449,8 @@ public class UserManager { public static final String DISALLOW_RECORD_AUDIO = "no_record_audio"; /** + * Allows apps in the parent profile to handle web links from the managed profile. + * * This user restriction has an effect only in a managed profile. * If set: * Intent filters of activities in the parent profile with action @@ -462,7 +464,8 @@ public class UserManager { * @see #setUserRestrictions(Bundle) * @see #getUserRestrictions() */ - public static final String ALLOW_PARENT_APP_LINKING = "allow_parent_app_linking"; + public static final String ALLOW_PARENT_PROFILE_APP_LINKING + = "allow_parent_profile_app_linking"; /** * Application restriction key that is used to indicate the pending arrival @@ -569,6 +572,16 @@ public class UserManager { } /** + * @hide + * Returns whether the caller is running as an admin user. There can be more than one admin + * user. + */ + public boolean isAdminUser() { + UserInfo user = getUserInfo(UserHandle.myUserId()); + return user != null ? user.isAdmin() : false; + } + + /** * Used to check if the user making this call is linked to another user. Linked users may have * a reduced number of available apps, app restrictions and account restrictions. * @return whether the user making this call is a linked user diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java index 9b5fbfa..e5afdde 100644 --- a/core/java/android/provider/Settings.java +++ b/core/java/android/provider/Settings.java @@ -562,6 +562,21 @@ public final class Settings { "android.settings.MANAGE_ALL_APPLICATIONS_SETTINGS"; /** + * Activity Action: Show settings to toggle permission to draw on top of + * other apps. + * <p> + * In some cases, a matching Activity may not exist, so ensure you + * safeguard against this. + * <p> + * Input: Nothing. + * <p> + * Output: Nothing. + */ + @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION) + public static final String ACTION_MANAGE_OVERLAY_PERMISSION = + "android.settings.MANAGE_OVERLAY_PERMISSION"; + + /** * Activity Action: Show screen of details about a particular application. * <p> * In some cases, a matching Activity may not exist, so ensure you @@ -5444,6 +5459,14 @@ public final class Settings { public static final String ASSIST_STRUCTURE_ENABLED = "assist_structure_enabled"; /** + * Specifies whether a screenshot of the screen contents will be sent to the assist + * application (active voice interaction service). + * + * @hide + */ + public static final String ASSIST_SCREENSHOT_ENABLED = "assist_screenshot_enabled"; + + /** * Names of the service components that the current user has explicitly allowed to * see all of the user's notifications, separated by ':'. * diff --git a/core/java/android/service/voice/VoiceInteractionService.java b/core/java/android/service/voice/VoiceInteractionService.java index 8119049..549c93e 100644 --- a/core/java/android/service/voice/VoiceInteractionService.java +++ b/core/java/android/service/voice/VoiceInteractionService.java @@ -172,15 +172,6 @@ public class VoiceInteractionService extends Service { } } - /** @hide */ - public void startSession(Bundle args, int flags) { - showSession(args, flags); - } - /** @hide */ - public void startSession(Bundle args) { - startSession(args, 0); - } - @Override public void onCreate() { super.onCreate(); diff --git a/core/java/android/service/voice/VoiceInteractionSession.java b/core/java/android/service/voice/VoiceInteractionSession.java index f9e216a..7eb936a 100644 --- a/core/java/android/service/voice/VoiceInteractionSession.java +++ b/core/java/android/service/voice/VoiceInteractionSession.java @@ -71,7 +71,7 @@ import static android.view.ViewGroup.LayoutParams.MATCH_PARENT; */ public class VoiceInteractionSession implements KeyEvent.Callback, ComponentCallbacks2 { static final String TAG = "VoiceInteractionSession"; - static final boolean DEBUG = true; + static final boolean DEBUG = false; /** * Flag received in {@link #onShow}: originator requested that the session be started with @@ -175,6 +175,7 @@ public class VoiceInteractionSession implements KeyEvent.Callback, ComponentCall CommandRequest request = new CommandRequest(callingPackage, Binder.getCallingUid(), callback, VoiceInteractionSession.this, command, extras); + addRequest(request); mHandlerCaller.sendMessage(mHandlerCaller.obtainMessageO(MSG_START_COMMAND, request)); return request.mInterface; @@ -249,16 +250,12 @@ public class VoiceInteractionSession implements KeyEvent.Callback, ComponentCall } }; - /** @hide */ - public static class Caller { - } - /** * Base class representing a request from a voice-driver app to perform a particular * voice operation with the user. See related subclasses for the types of requests * that are possible. */ - public static class Request extends Caller { + public static class Request { final IVoiceInteractorRequest mInterface = new IVoiceInteractorRequest.Stub() { @Override public void cancel() throws RemoteException { @@ -319,74 +316,8 @@ public class VoiceInteractionSession implements KeyEvent.Callback, ComponentCall } } - /** @hide */ - public void sendConfirmResult(boolean confirmed, Bundle result) { - try { - if (DEBUG) Log.d(TAG, "sendConfirmResult: req=" + mInterface - + " confirmed=" + confirmed + " result=" + result); - finishRequest(); - mCallback.deliverConfirmationResult(mInterface, confirmed, result); - } catch (RemoteException e) { - } - } - - /** @hide */ - public void sendPickOptionResult(boolean finished, - VoiceInteractor.PickOptionRequest.Option[] selections, Bundle result) { - try { - if (DEBUG) Log.d(TAG, "sendPickOptionResult: req=" + mInterface - + " finished=" + finished + " selections=" + selections - + " result=" + result); - if (finished) { - finishRequest(); - } - mCallback.deliverPickOptionResult(mInterface, finished, selections, result); - } catch (RemoteException e) { - } - } - - /** @hide */ - public void sendCompleteVoiceResult(Bundle result) { - try { - if (DEBUG) Log.d(TAG, "sendCompleteVoiceResult: req=" + mInterface - + " result=" + result); - finishRequest(); - mCallback.deliverCompleteVoiceResult(mInterface, result); - } catch (RemoteException e) { - } - } - - /** @hide */ - public void sendAbortVoiceResult(Bundle result) { - try { - if (DEBUG) Log.d(TAG, "sendConfirmResult: req=" + mInterface - + " result=" + result); - finishRequest(); - mCallback.deliverAbortVoiceResult(mInterface, result); - } catch (RemoteException e) { - } - } - - /** @hide */ - public void sendCommandResult(boolean finished, Bundle result) { - try { - if (DEBUG) Log.d(TAG, "sendCommandResult: req=" + mInterface - + " result=" + result); - if (finished) { - finishRequest(); - } - mCallback.deliverCommandResult(mInterface, finished, result); - } catch (RemoteException e) { - } - } - - /** @hide */ - public void sendCancelResult() { - cancel(); - } - /** - * ASk the app to cancelLocked this current request. + * Ask the app to cancel this current request. */ public void cancel() { try { @@ -440,7 +371,13 @@ public class VoiceInteractionSession implements KeyEvent.Callback, ComponentCall * VoiceInteractor.ConfirmationRequest.onConfirmationResult}. */ public void sendConfirmationResult(boolean confirmed, Bundle result) { - sendConfirmResult(confirmed, result); + try { + if (DEBUG) Log.d(TAG, "sendConfirmationResult: req=" + mInterface + + " confirmed=" + confirmed + " result=" + result); + finishRequest(); + mCallback.deliverConfirmationResult(mInterface, confirmed, result); + } catch (RemoteException e) { + } } } @@ -487,6 +424,20 @@ public class VoiceInteractionSession implements KeyEvent.Callback, ComponentCall return mOptions; } + void sendPickOptionResult(boolean finished, + VoiceInteractor.PickOptionRequest.Option[] selections, Bundle result) { + try { + if (DEBUG) Log.d(TAG, "sendPickOptionResult: req=" + mInterface + + " finished=" + finished + " selections=" + selections + + " result=" + result); + if (finished) { + finishRequest(); + } + mCallback.deliverPickOptionResult(mInterface, finished, selections, result); + } catch (RemoteException e) { + } + } + /** * Report an intermediate option selection from the request, without completing it (the * request is still active and the app is waiting for the final option selection), @@ -553,7 +504,13 @@ public class VoiceInteractionSession implements KeyEvent.Callback, ComponentCall * VoiceInteractor.CompleteVoiceRequest.onCompleteResult}. */ public void sendCompleteResult(Bundle result) { - sendCompleteVoiceResult(result); + try { + if (DEBUG) Log.d(TAG, "sendCompleteVoiceResult: req=" + mInterface + + " result=" + result); + finishRequest(); + mCallback.deliverCompleteVoiceResult(mInterface, result); + } catch (RemoteException e) { + } } } @@ -596,7 +553,13 @@ public class VoiceInteractionSession implements KeyEvent.Callback, ComponentCall * VoiceInteractor.AbortVoiceRequest.onAbortResult}. */ public void sendAbortResult(Bundle result) { - sendAbortVoiceResult(result); + try { + if (DEBUG) Log.d(TAG, "sendConfirmResult: req=" + mInterface + + " result=" + result); + finishRequest(); + mCallback.deliverAbortVoiceResult(mInterface, result); + } catch (RemoteException e) { + } } } @@ -621,6 +584,18 @@ public class VoiceInteractionSession implements KeyEvent.Callback, ComponentCall return mCommand; } + void sendCommandResult(boolean finished, Bundle result) { + try { + if (DEBUG) Log.d(TAG, "sendCommandResult: req=" + mInterface + + " result=" + result); + if (finished) { + finishRequest(); + } + mCallback.deliverCommandResult(mInterface, finished, result); + } catch (RemoteException e) { + } + } + /** * Report an intermediate result of the request, without completing it (the request * is still active and the app is waiting for the final result), resulting in a call to @@ -829,11 +804,10 @@ public class VoiceInteractionSession implements KeyEvent.Callback, ComponentCall } } - void doCreate(IVoiceInteractionManagerService service, IBinder token, Bundle args, - int startFlags) { + void doCreate(IVoiceInteractionManagerService service, IBinder token) { mSystemService = service; mToken = token; - onCreate(args, startFlags); + onCreate(); } void doShow(Bundle args, int flags, final IVoiceInteractionSessionShowCallback showCallback) { @@ -919,11 +893,6 @@ public class VoiceInteractionSession implements KeyEvent.Callback, ComponentCall mContentFrame = (FrameLayout)mRootView.findViewById(android.R.id.content); } - /** @hide */ - public void show() { - show(null, 0); - } - /** * Show the UI for this session. This asks the system to go through the process of showing * your UI, which will eventually culminate in {@link #onShow}. This is similar to calling @@ -958,14 +927,6 @@ public class VoiceInteractionSession implements KeyEvent.Callback, ComponentCall } } - /** @hide */ - public void showWindow() { - } - - /** @hide */ - public void hideWindow() { - } - /** * You can call this to customize the theme used by your IME's window. * This must be set before {@link #onCreate}, so you @@ -1062,7 +1023,6 @@ public class VoiceInteractionSession implements KeyEvent.Callback, ComponentCall if (mToken == null) { throw new IllegalStateException("Can't call before onCreate()"); } - hideWindow(); try { mSystemService.finish(mToken); } catch (RemoteException e) { @@ -1077,16 +1037,6 @@ public class VoiceInteractionSession implements KeyEvent.Callback, ComponentCall doOnCreate(); } - /** @hide */ - public void onCreate(Bundle args) { - doOnCreate(); - } - - /** @hide */ - public void onCreate(Bundle args, int showFlags) { - doOnCreate(); - } - private void doOnCreate() { mTheme = mTheme != 0 ? mTheme : com.android.internal.R.style.Theme_DeviceDefault_VoiceInteractionSession; @@ -1244,34 +1194,6 @@ public class VoiceInteractionSession implements KeyEvent.Callback, ComponentCall hide(); } - /** @hide */ - public boolean[] onGetSupportedCommands(Caller caller, String[] commands) { - return new boolean[commands.length]; - } - /** @hide */ - public void onConfirm(Caller caller, Request request, CharSequence prompt, - Bundle extras) { - } - /** @hide */ - public void onPickOption(Caller caller, Request request, CharSequence prompt, - VoiceInteractor.PickOptionRequest.Option[] options, Bundle extras) { - } - /** @hide */ - public void onCompleteVoice(Caller caller, Request request, CharSequence message, - Bundle extras) { - request.sendCompleteVoiceResult(null); - } - /** @hide */ - public void onAbortVoice(Caller caller, Request request, CharSequence message, Bundle extras) { - request.sendAbortVoiceResult(null); - } - /** @hide */ - public void onCommand(Caller caller, Request request, String command, Bundle extras) { - } - /** @hide */ - public void onCancel(Request request) { - } - /** * Request to query for what extended commands the session supports. * @@ -1282,7 +1204,7 @@ public class VoiceInteractionSession implements KeyEvent.Callback, ComponentCall * an array of all false entries. */ public boolean[] onGetSupportedCommands(String[] commands) { - return onGetSupportedCommands(new Caller(), commands); + return new boolean[commands.length]; } /** @@ -1293,7 +1215,6 @@ public class VoiceInteractionSession implements KeyEvent.Callback, ComponentCall * @param request The active request. */ public void onRequestConfirmation(ConfirmationRequest request) { - onConfirm(request, request, request.getPrompt(), request.getExtras()); } /** @@ -1303,8 +1224,6 @@ public class VoiceInteractionSession implements KeyEvent.Callback, ComponentCall * @param request The active request. */ public void onRequestPickOption(PickOptionRequest request) { - onPickOption(request, request, request.getPrompt(), request.getOptions(), - request.getExtras()); } /** @@ -1317,7 +1236,6 @@ public class VoiceInteractionSession implements KeyEvent.Callback, ComponentCall * @param request The active request. */ public void onRequestCompleteVoice(CompleteVoiceRequest request) { - onCompleteVoice(request, request, request.getMessage(), request.getExtras()); } /** @@ -1330,7 +1248,6 @@ public class VoiceInteractionSession implements KeyEvent.Callback, ComponentCall * @param request The active request. */ public void onRequestAbortVoice(AbortVoiceRequest request) { - onAbortVoice(request, request, request.getMessage(), request.getExtras()); } /** @@ -1341,11 +1258,10 @@ public class VoiceInteractionSession implements KeyEvent.Callback, ComponentCall * @param request The active request. */ public void onRequestCommand(CommandRequest request) { - onCommand(request, request, request.getCommand(), request.getExtras()); } /** - * Called when the {@link android.app.VoiceInteractor} has asked to cancelLocked a {@link Request} + * Called when the {@link android.app.VoiceInteractor} has asked to cancel a {@link Request} * that was previously delivered to {@link #onRequestConfirmation}, * {@link #onRequestPickOption}, {@link #onRequestCompleteVoice}, {@link #onRequestAbortVoice}, * or {@link #onRequestCommand}. @@ -1353,6 +1269,5 @@ public class VoiceInteractionSession implements KeyEvent.Callback, ComponentCall * @param request The request that is being canceled. */ public void onCancelRequest(Request request) { - onCancel(request); } } diff --git a/core/java/android/service/voice/VoiceInteractionSessionService.java b/core/java/android/service/voice/VoiceInteractionSessionService.java index 8f988f3..fb9f973 100644 --- a/core/java/android/service/voice/VoiceInteractionSessionService.java +++ b/core/java/android/service/voice/VoiceInteractionSessionService.java @@ -109,7 +109,7 @@ public abstract class VoiceInteractionSessionService extends Service { mSession = onNewSession(args); try { mSystemService.deliverNewSession(token, mSession.mSession, mSession.mInteractor); - mSession.doCreate(mSystemService, token, args, startFlags); + mSession.doCreate(mSystemService, token); } catch (RemoteException e) { } } diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java index 23da6d2..63dd492 100644 --- a/core/java/android/view/View.java +++ b/core/java/android/view/View.java @@ -12288,6 +12288,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, mRenderNode.offsetTopAndBottom(offset); if (isHardwareAccelerated()) { invalidateViewProperty(false, false); + invalidateParentIfNeededAndWasQuickRejected(); } else { if (!matrixIsIdentity) { invalidateViewProperty(false, true); @@ -12335,6 +12336,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, mRenderNode.offsetLeftAndRight(offset); if (isHardwareAccelerated()) { invalidateViewProperty(false, false); + invalidateParentIfNeededAndWasQuickRejected(); } else { if (!matrixIsIdentity) { invalidateViewProperty(false, true); diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java index b53d93c..6dca26b 100644 --- a/core/java/android/view/ViewGroup.java +++ b/core/java/android/view/ViewGroup.java @@ -3236,13 +3236,15 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager for (int i = 0; i < getChildCount(); i++) { View c = getChildAt(i); - Insets insets = c.getOpticalInsets(); - - drawRect(canvas, paint, - c.getLeft() + insets.left, - c.getTop() + insets.top, - c.getRight() - insets.right - 1, - c.getBottom() - insets.bottom - 1); + if (c.getVisibility() != View.GONE) { + Insets insets = c.getOpticalInsets(); + + drawRect(canvas, paint, + c.getLeft() + insets.left, + c.getTop() + insets.top, + c.getRight() - insets.right - 1, + c.getBottom() - insets.bottom - 1); + } } } @@ -3263,8 +3265,10 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager int lineWidth = dipsToPixels(1); for (int i = 0; i < getChildCount(); i++) { View c = getChildAt(i); - drawRectCorners(canvas, c.getLeft(), c.getTop(), c.getRight(), c.getBottom(), - paint, lineLength, lineWidth); + if (c.getVisibility() != View.GONE) { + drawRectCorners(canvas, c.getLeft(), c.getTop(), c.getRight(), c.getBottom(), + paint, lineLength, lineWidth); + } } } } diff --git a/core/java/android/view/WindowManagerPolicy.java b/core/java/android/view/WindowManagerPolicy.java index ca5f5ad..dd6d3ca 100644 --- a/core/java/android/view/WindowManagerPolicy.java +++ b/core/java/android/view/WindowManagerPolicy.java @@ -913,12 +913,13 @@ public interface WindowManagerPolicy { /** * Called following layout of all window to apply policy to each window. - * + * * @param win The window being positioned. - * @param attrs The LayoutParams of the window. + * @param attrs The LayoutParams of the window. + * @param attached For sub-windows, the window it is attached to. Otherwise null. */ public void applyPostLayoutPolicyLw(WindowState win, - WindowManager.LayoutParams attrs); + WindowManager.LayoutParams attrs, WindowState attached); /** * Called following layout of all windows and after policy has been applied diff --git a/core/java/android/view/accessibility/AccessibilityEvent.java b/core/java/android/view/accessibility/AccessibilityEvent.java index 87706ef..1464bb5 100644 --- a/core/java/android/view/accessibility/AccessibilityEvent.java +++ b/core/java/android/view/accessibility/AccessibilityEvent.java @@ -689,6 +689,11 @@ public final class AccessibilityEvent extends AccessibilityRecord implements Par public static final int TYPE_VIEW_CONTEXT_CLICKED = 0x00800000; /** + * Represents the event of the assistant currently reading the users screen context. + */ + public static final int TYPE_ASSIST_READING_CONTEXT = 0x01000000; + + /** * Change type for {@link #TYPE_WINDOW_CONTENT_CHANGED} event: * The type of change is not defined. */ @@ -1414,6 +1419,13 @@ public final class AccessibilityEvent extends AccessibilityRecord implements Par builder.append("TYPE_VIEW_CONTEXT_CLICKED"); eventTypeCount++; } + case TYPE_ASSIST_READING_CONTEXT: { + if (eventTypeCount > 0) { + builder.append(", "); + } + builder.append("TYPE_ASSIST_READING_CONTEXT"); + eventTypeCount++; + } break; } } diff --git a/core/java/android/widget/CompoundButton.java b/core/java/android/widget/CompoundButton.java index 770077d..602e1ab 100644 --- a/core/java/android/widget/CompoundButton.java +++ b/core/java/android/widget/CompoundButton.java @@ -245,6 +245,17 @@ public abstract class CompoundButton extends Button implements Checkable { } /** + * @hide + */ + @Override + public void onResolveDrawables(@ResolvedLayoutDir int layoutDirection) { + super.onResolveDrawables(layoutDirection); + if (mButtonDrawable != null) { + mButtonDrawable.setLayoutDirection(layoutDirection); + } + } + + /** * @return the drawable used as the compound button image * @see #setButtonDrawable(Drawable) * @see #setButtonDrawable(int) diff --git a/core/java/android/widget/ImageView.java b/core/java/android/widget/ImageView.java index e0b2395..a1582f2 100644 --- a/core/java/android/widget/ImageView.java +++ b/core/java/android/widget/ImageView.java @@ -423,14 +423,14 @@ public class ImageView extends View { * * <p class="note">This does Bitmap reading and decoding on the UI * thread, which can cause a latency hiccup. If that's a concern, - * consider using {@link #setImageDrawable(android.graphics.drawable.Drawable)} or + * consider using {@link #setImageDrawable(Drawable)} or * {@link #setImageBitmap(android.graphics.Bitmap)} and * {@link android.graphics.BitmapFactory} instead.</p> * - * @param uri The Uri of an image + * @param uri the Uri of an image, or {@code null} to clear the content */ @android.view.RemotableViewMethod - public void setImageURI(Uri uri) { + public void setImageURI(@Nullable Uri uri) { if (mResource != 0 || (mUri != uri && (uri == null || mUri == null || !uri.equals(mUri)))) { @@ -453,9 +453,10 @@ public class ImageView extends View { /** * Sets a drawable as the content of this ImageView. * - * @param drawable The drawable to set + * @param drawable the Drawable to set, or {@code null} to clear the + * content */ - public void setImageDrawable(Drawable drawable) { + public void setImageDrawable(@Nullable Drawable drawable) { if (mDrawable != drawable) { mResource = 0; mUri = null; @@ -475,16 +476,19 @@ public class ImageView extends View { /** * Sets the content of this ImageView to the specified Icon. * - * <p class="note">Depending on the Icon type, this may do Bitmap reading and decoding - * on the UI thread, which can cause UI jank. If that's a concern, consider using + * <p class="note">Depending on the Icon type, this may do Bitmap reading + * and decoding on the UI thread, which can cause UI jank. If that's a + * concern, consider using * {@link Icon#loadDrawableAsync(Context, Icon.OnDrawableLoadedListener, Handler)} - * and then {@link #setImageDrawable(android.graphics.drawable.Drawable)} instead.</p> + * and then {@link #setImageDrawable(android.graphics.drawable.Drawable)} + * instead.</p> * - * @param icon an Icon holding the desired image + * @param icon an Icon holding the desired image, or {@code null} to clear + * the content */ @android.view.RemotableViewMethod - public void setImageIcon(Icon icon) { - setImageDrawable(icon.loadDrawable(mContext)); + public void setImageIcon(@Nullable Icon icon) { + setImageDrawable(icon == null ? null : icon.loadDrawable(mContext)); } /** diff --git a/core/java/android/widget/LinearLayout.java b/core/java/android/widget/LinearLayout.java index 4dcc242..b5e08ca 100644 --- a/core/java/android/widget/LinearLayout.java +++ b/core/java/android/widget/LinearLayout.java @@ -659,7 +659,8 @@ public class LinearLayout extends ViewGroup { */ private boolean allViewsAreGoneBefore(int childIndex) { for (int i = childIndex - 1; i >= 0; i--) { - if (getVirtualChildAt(i).getVisibility() != GONE) { + View child = getVirtualChildAt(i); + if (child != null && child.getVisibility() != GONE) { return false; } } diff --git a/core/java/android/widget/ListView.java b/core/java/android/widget/ListView.java index fd0395a..9568492 100644 --- a/core/java/android/widget/ListView.java +++ b/core/java/android/widget/ListView.java @@ -1143,8 +1143,8 @@ public class ListView extends AbsListView { // Sets up mListPadding super.onMeasure(widthMeasureSpec, heightMeasureSpec); - int widthMode = MeasureSpec.getMode(widthMeasureSpec); - int heightMode = MeasureSpec.getMode(heightMeasureSpec); + final int widthMode = MeasureSpec.getMode(widthMeasureSpec); + final int heightMode = MeasureSpec.getMode(heightMeasureSpec); int widthSize = MeasureSpec.getSize(widthMeasureSpec); int heightSize = MeasureSpec.getSize(heightMeasureSpec); @@ -1153,10 +1153,12 @@ public class ListView extends AbsListView { int childState = 0; mItemCount = mAdapter == null ? 0 : mAdapter.getCount(); - if (mItemCount > 0 && (widthMode == MeasureSpec.UNSPECIFIED || - heightMode == MeasureSpec.UNSPECIFIED)) { + if (mItemCount > 0 && (widthMode == MeasureSpec.UNSPECIFIED + || heightMode == MeasureSpec.UNSPECIFIED)) { final View child = obtainView(0, mIsScrap); + // Lay out child directly against the parent measure spec so that + // we can obtain exected minimum width and height. measureScrapChild(child, 0, widthMeasureSpec, heightSize); childWidth = child.getMeasuredWidth(); @@ -1173,7 +1175,7 @@ public class ListView extends AbsListView { widthSize = mListPadding.left + mListPadding.right + childWidth + getVerticalScrollbarWidth(); } else { - widthSize |= (childState&MEASURED_STATE_MASK); + widthSize |= (childState & MEASURED_STATE_MASK); } if (heightMode == MeasureSpec.UNSPECIFIED) { @@ -1186,8 +1188,9 @@ public class ListView extends AbsListView { heightSize = measureHeightOfChildren(widthMeasureSpec, 0, NO_POSITION, heightSize, -1); } - setMeasuredDimension(widthSize , heightSize); - mWidthMeasureSpec = widthMeasureSpec; + setMeasuredDimension(widthSize, heightSize); + + mWidthMeasureSpec = widthMeasureSpec; } private void measureScrapChild(View child, int position, int widthMeasureSpec, int heightHint) { @@ -1199,16 +1202,20 @@ public class ListView extends AbsListView { p.viewType = mAdapter.getItemViewType(position); p.forceAdd = true; - int childWidthSpec = ViewGroup.getChildMeasureSpec(widthMeasureSpec, + final int childWidthSpec = ViewGroup.getChildMeasureSpec(widthMeasureSpec, mListPadding.left + mListPadding.right, p.width); - int lpHeight = p.height; - int childHeightSpec; + final int lpHeight = p.height; + final int childHeightSpec; if (lpHeight > 0) { childHeightSpec = MeasureSpec.makeMeasureSpec(lpHeight, MeasureSpec.EXACTLY); } else { childHeightSpec = MeasureSpec.makeSafeMeasureSpec(heightHint, MeasureSpec.UNSPECIFIED); } child.measure(childWidthSpec, childHeightSpec); + + // Since this view was measured directly aginst the parent measure + // spec, we must measure it again before reuse. + child.forceLayout(); } /** @@ -1248,8 +1255,7 @@ public class ListView extends AbsListView { * @return The height of this ListView with the given children. */ final int measureHeightOfChildren(int widthMeasureSpec, int startPosition, int endPosition, - final int maxHeight, int disallowPartialChildPosition) { - + int maxHeight, int disallowPartialChildPosition) { final ListAdapter adapter = mAdapter; if (adapter == null) { return mListPadding.top + mListPadding.bottom; @@ -1907,8 +1913,8 @@ public class ListView extends AbsListView { } p.viewType = mAdapter.getItemViewType(position); - if ((recycled && !p.forceAdd) || (p.recycledHeaderFooter && - p.viewType == AdapterView.ITEM_VIEW_TYPE_HEADER_OR_FOOTER)) { + if ((recycled && !p.forceAdd) || (p.recycledHeaderFooter + && p.viewType == AdapterView.ITEM_VIEW_TYPE_HEADER_OR_FOOTER)) { attachViewToParent(child, flowDown ? -1 : 0, p); } else { p.forceAdd = false; @@ -1936,10 +1942,10 @@ public class ListView extends AbsListView { } if (needToMeasure) { - int childWidthSpec = ViewGroup.getChildMeasureSpec(mWidthMeasureSpec, + final int childWidthSpec = ViewGroup.getChildMeasureSpec(mWidthMeasureSpec, mListPadding.left + mListPadding.right, p.width); - int lpHeight = p.height; - int childHeightSpec; + final int lpHeight = p.height; + final int childHeightSpec; if (lpHeight > 0) { childHeightSpec = MeasureSpec.makeMeasureSpec(lpHeight, MeasureSpec.EXACTLY); } else { diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java index 7b58b5b..422511f 100644 --- a/core/java/android/widget/TextView.java +++ b/core/java/android/widget/TextView.java @@ -8837,12 +8837,10 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener | AccessibilityNodeInfo.MOVEMENT_GRANULARITY_LINE | AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PARAGRAPH | AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PAGE); + info.addAction(AccessibilityNodeInfo.ACTION_SET_SELECTION); } if (isFocused()) { - if (canSelectText()) { - info.addAction(AccessibilityNodeInfo.ACTION_SET_SELECTION); - } if (canCopy()) { info.addAction(AccessibilityNodeInfo.ACTION_COPY); } @@ -8931,30 +8929,28 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener } } return false; case AccessibilityNodeInfo.ACTION_SET_SELECTION: { - if (isFocused() && canSelectText()) { - ensureIterableTextForAccessibilitySelectable(); - CharSequence text = getIterableTextForAccessibility(); - if (text == null) { - return false; + ensureIterableTextForAccessibilitySelectable(); + CharSequence text = getIterableTextForAccessibility(); + if (text == null) { + return false; + } + final int start = (arguments != null) ? arguments.getInt( + AccessibilityNodeInfo.ACTION_ARGUMENT_SELECTION_START_INT, -1) : -1; + final int end = (arguments != null) ? arguments.getInt( + AccessibilityNodeInfo.ACTION_ARGUMENT_SELECTION_END_INT, -1) : -1; + if ((getSelectionStart() != start || getSelectionEnd() != end)) { + // No arguments clears the selection. + if (start == end && end == -1) { + Selection.removeSelection((Spannable) text); + return true; } - final int start = (arguments != null) ? arguments.getInt( - AccessibilityNodeInfo.ACTION_ARGUMENT_SELECTION_START_INT, -1) : -1; - final int end = (arguments != null) ? arguments.getInt( - AccessibilityNodeInfo.ACTION_ARGUMENT_SELECTION_END_INT, -1) : -1; - if ((getSelectionStart() != start || getSelectionEnd() != end)) { - // No arguments clears the selection. - if (start == end && end == -1) { - Selection.removeSelection((Spannable) text); - return true; - } - if (start >= 0 && start <= end && end <= text.length()) { - Selection.setSelection((Spannable) text, start, end); - // Make sure selection mode is engaged. - if (mEditor != null) { - mEditor.startSelectionActionMode(); - } - return true; + if (start >= 0 && start <= end && end <= text.length()) { + Selection.setSelection((Spannable) text, start, end); + // Make sure selection mode is engaged. + if (mEditor != null) { + mEditor.startSelectionActionMode(); } + return true; } } } return false; |
