diff options
Diffstat (limited to 'core/java')
38 files changed, 657 insertions, 335 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; diff --git a/core/java/com/android/internal/app/MediaRouteControllerDialog.java b/core/java/com/android/internal/app/MediaRouteControllerDialog.java index b0e0373..4a468be 100644 --- a/core/java/com/android/internal/app/MediaRouteControllerDialog.java +++ b/core/java/com/android/internal/app/MediaRouteControllerDialog.java @@ -18,7 +18,7 @@ package com.android.internal.app; import com.android.internal.R; -import android.app.Dialog; +import android.app.AlertDialog; import android.app.MediaRouteActionProvider; import android.app.MediaRouteButton; import android.content.Context; @@ -46,7 +46,7 @@ import android.widget.SeekBar; * * TODO: Move this back into the API, as in the support library media router. */ -public class MediaRouteControllerDialog extends Dialog { +public class MediaRouteControllerDialog extends AlertDialog { // Time to wait before updating the volume when the user lets go of the seek bar // to allow the route provider time to propagate the change and publish a new // route descriptor. @@ -134,8 +134,6 @@ public class MediaRouteControllerDialog extends Dialog { protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - getWindow().requestFeature(Window.FEATURE_LEFT_ICON); - setContentView(R.layout.media_route_controller_dialog); mVolumeLayout = (LinearLayout)findViewById(R.id.media_route_volume_layout); diff --git a/core/java/com/android/internal/inputmethod/InputMethodUtils.java b/core/java/com/android/internal/inputmethod/InputMethodUtils.java index ac17cbe..742173b 100644 --- a/core/java/com/android/internal/inputmethod/InputMethodUtils.java +++ b/core/java/com/android/internal/inputmethod/InputMethodUtils.java @@ -1302,4 +1302,131 @@ public class InputMethodUtils { return enabledInputMethodAndSubtypes; } } + + // For spell checker service manager. + // TODO: Should we have TextServicesUtils.java? + private static final Locale LOCALE_EN_US = new Locale("en", "US"); + private static final Locale LOCALE_EN_GB = new Locale("en", "GB"); + + /** + * Returns a list of {@link Locale} in the order of appropriateness for the default spell + * checker service. + * + * <p>If the system language is English, and the region is also explicitly specified in the + * system locale, the following fallback order will be applied.</p> + * <ul> + * <li>(system-locale-language, system-locale-region, system-locale-variant) (if exists)</li> + * <li>(system-locale-language, system-locale-region)</li> + * <li>("en", "US")</li> + * <li>("en", "GB")</li> + * <li>("en")</li> + * </ul> + * + * <p>If the system language is English, but no region is specified in the system locale, + * the following fallback order will be applied.</p> + * <ul> + * <li>("en")</li> + * <li>("en", "US")</li> + * <li>("en", "GB")</li> + * </ul> + * + * <p>If the system language is not English, the following fallback order will be applied.</p> + * <ul> + * <li>(system-locale-language, system-locale-region, system-locale-variant) (if exists)</li> + * <li>(system-locale-language, system-locale-region) (if exists)</li> + * <li>(system-locale-language) (if exists)</li> + * <li>("en", "US")</li> + * <li>("en", "GB")</li> + * <li>("en")</li> + * </ul> + * + * @param systemLocale the current system locale to be taken into consideration. + * @return a list of {@link Locale}. The first one is considered to be most appropriate. + */ + @VisibleForTesting + public static ArrayList<Locale> getSuitableLocalesForSpellChecker( + @Nullable final Locale systemLocale) { + final Locale systemLocaleLanguageCountryVariant; + final Locale systemLocaleLanguageCountry; + final Locale systemLocaleLanguage; + if (systemLocale != null) { + final String language = systemLocale.getLanguage(); + final boolean hasLanguage = !TextUtils.isEmpty(language); + final String country = systemLocale.getCountry(); + final boolean hasCountry = !TextUtils.isEmpty(country); + final String variant = systemLocale.getVariant(); + final boolean hasVariant = !TextUtils.isEmpty(variant); + if (hasLanguage && hasCountry && hasVariant) { + systemLocaleLanguageCountryVariant = new Locale(language, country, variant); + } else { + systemLocaleLanguageCountryVariant = null; + } + if (hasLanguage && hasCountry) { + systemLocaleLanguageCountry = new Locale(language, country); + } else { + systemLocaleLanguageCountry = null; + } + if (hasLanguage) { + systemLocaleLanguage = new Locale(language); + } else { + systemLocaleLanguage = null; + } + } else { + systemLocaleLanguageCountryVariant = null; + systemLocaleLanguageCountry = null; + systemLocaleLanguage = null; + } + + final ArrayList<Locale> locales = new ArrayList<>(); + if (systemLocaleLanguageCountryVariant != null) { + locales.add(systemLocaleLanguageCountryVariant); + } + + if (Locale.ENGLISH.equals(systemLocaleLanguage)) { + if (systemLocaleLanguageCountry != null) { + // If the system language is English, and the region is also explicitly specified, + // following fallback order will be applied. + // - systemLocaleLanguageCountry [if systemLocaleLanguageCountry is non-null] + // - en_US [if systemLocaleLanguageCountry is non-null and not en_US] + // - en_GB [if systemLocaleLanguageCountry is non-null and not en_GB] + // - en + if (systemLocaleLanguageCountry != null) { + locales.add(systemLocaleLanguageCountry); + } + if (!LOCALE_EN_US.equals(systemLocaleLanguageCountry)) { + locales.add(LOCALE_EN_US); + } + if (!LOCALE_EN_GB.equals(systemLocaleLanguageCountry)) { + locales.add(LOCALE_EN_GB); + } + locales.add(Locale.ENGLISH); + } else { + // If the system language is English, but no region is specified, following + // fallback order will be applied. + // - en + // - en_US + // - en_GB + locales.add(Locale.ENGLISH); + locales.add(LOCALE_EN_US); + locales.add(LOCALE_EN_GB); + } + } else { + // If the system language is not English, the fallback order will be + // - systemLocaleLanguageCountry [if non-null] + // - systemLocaleLanguage [if non-null] + // - en_US + // - en_GB + // - en + if (systemLocaleLanguageCountry != null) { + locales.add(systemLocaleLanguageCountry); + } + if (systemLocaleLanguage != null) { + locales.add(systemLocaleLanguage); + } + locales.add(LOCALE_EN_US); + locales.add(LOCALE_EN_GB); + locales.add(Locale.ENGLISH); + } + return locales; + } } diff --git a/core/java/com/android/internal/logging/MetricsLogger.java b/core/java/com/android/internal/logging/MetricsLogger.java index b78eca7..263e522 100644 --- a/core/java/com/android/internal/logging/MetricsLogger.java +++ b/core/java/com/android/internal/logging/MetricsLogger.java @@ -40,6 +40,10 @@ public class MetricsLogger implements MetricsConstants { public static final int ACTION_BRIGHTNESS = 218; public static final int ACTION_BRIGHTNESS_AUTO = 219; public static final int BRIGHTNESS_DIALOG = 220; + public static final int SYSTEM_ALERT_WINDOW_APPS = 221; + public static final int DREAMING = 222; + public static final int DOZING = 223; + // Temporary constants go here, to await migration to MetricsConstants. public static void visible(Context context, int category) throws IllegalArgumentException { diff --git a/core/java/com/android/internal/os/BatteryStatsHelper.java b/core/java/com/android/internal/os/BatteryStatsHelper.java index 6a85afb..264b8c1 100644 --- a/core/java/com/android/internal/os/BatteryStatsHelper.java +++ b/core/java/com/android/internal/os/BatteryStatsHelper.java @@ -480,6 +480,7 @@ public final class BatteryStatsHelper { final boolean forAllUsers = (asUsers.get(UserHandle.USER_ALL) != null); mStatsPeriod = mTypeBatteryRealtime; + BatterySipper osSipper = null; final SparseArray<? extends Uid> uidStats = mStats.getUidStats(); final int NU = uidStats.size(); for (int iu = 0; iu < NU; iu++) { @@ -526,15 +527,19 @@ public final class BatteryStatsHelper { } if (uid == 0) { - // The device has probably been awake for longer than the screen on - // time and application wake lock time would account for. Assign - // this remainder to the OS, if possible. - mWakelockPowerCalculator.calculateRemaining(app, mStats, mRawRealtime, - mRawUptime, mStatsType); - app.sumPower(); + osSipper = app; } } } + + if (osSipper != null) { + // The device has probably been awake for longer than the screen on + // time and application wake lock time would account for. Assign + // this remainder to the OS, if possible. + mWakelockPowerCalculator.calculateRemaining(osSipper, mStats, mRawRealtime, + mRawUptime, mStatsType); + osSipper.sumPower(); + } } private void addPhoneUsage() { diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java index 1bd821d..8b4b994 100644 --- a/core/java/com/android/internal/os/BatteryStatsImpl.java +++ b/core/java/com/android/internal/os/BatteryStatsImpl.java @@ -106,7 +106,7 @@ public final class BatteryStatsImpl extends BatteryStats { private static final int MAGIC = 0xBA757475; // 'BATSTATS' // Current on-disk Parcel version - private static final int VERSION = 129 + (USE_OLD_HISTORY ? 1000 : 0); + private static final int VERSION = 130 + (USE_OLD_HISTORY ? 1000 : 0); // Maximum number of items we will record in the history. private static final int MAX_HISTORY_ITEMS = 2000; @@ -4386,6 +4386,7 @@ public final class BatteryStatsImpl extends BatteryStats { LongSamplingCounter mUserCpuTime = new LongSamplingCounter(mOnBatteryTimeBase); LongSamplingCounter mSystemCpuTime = new LongSamplingCounter(mOnBatteryTimeBase); + LongSamplingCounter mCpuPower = new LongSamplingCounter(mOnBatteryTimeBase); LongSamplingCounter[] mSpeedBins; /** @@ -4978,6 +4979,11 @@ public final class BatteryStatsImpl extends BatteryStats { } @Override + public long getCpuPowerMaUs(int which) { + return mCpuPower.getCountLocked(which); + } + + @Override public long getTimeAtCpuSpeed(int step, int which) { if (step >= 0 && step < mSpeedBins.length) { if (mSpeedBins[step] != null) { @@ -5097,6 +5103,7 @@ public final class BatteryStatsImpl extends BatteryStats { mUserCpuTime.reset(false); mSystemCpuTime.reset(false); + mCpuPower.reset(false); for (int i = 0; i < mSpeedBins.length; i++) { LongSamplingCounter c = mSpeedBins[i]; if (c != null) { @@ -5248,6 +5255,7 @@ public final class BatteryStatsImpl extends BatteryStats { mUserCpuTime.detach(); mSystemCpuTime.detach(); + mCpuPower.detach(); for (int i = 0; i < mSpeedBins.length; i++) { LongSamplingCounter c = mSpeedBins[i]; if (c != null) { @@ -5427,6 +5435,7 @@ public final class BatteryStatsImpl extends BatteryStats { mUserCpuTime.writeToParcel(out); mSystemCpuTime.writeToParcel(out); + mCpuPower.writeToParcel(out); out.writeInt(mSpeedBins.length); for (int i = 0; i < mSpeedBins.length; i++) { @@ -5618,6 +5627,7 @@ public final class BatteryStatsImpl extends BatteryStats { mUserCpuTime = new LongSamplingCounter(mOnBatteryTimeBase, in); mSystemCpuTime = new LongSamplingCounter(mOnBatteryTimeBase, in); + mCpuPower = new LongSamplingCounter(mOnBatteryTimeBase, in); int bins = in.readInt(); int steps = getCpuSpeedSteps(); @@ -7964,7 +7974,8 @@ public final class BatteryStatsImpl extends BatteryStats { mKernelUidCpuTimeReader.readDelta(!mOnBatteryInternal ? null : new KernelUidCpuTimeReader.Callback() { @Override - public void onUidCpuTime(int uid, long userTimeUs, long systemTimeUs) { + public void onUidCpuTime(int uid, long userTimeUs, long systemTimeUs, + long powerMaUs) { final Uid u = getUidStatsLocked(mapUid(uid)); // Accumulate the total system and user time. @@ -7978,7 +7989,7 @@ public final class BatteryStatsImpl extends BatteryStats { TimeUtils.formatDuration(userTimeUs / 1000, sb); sb.append(" s="); TimeUtils.formatDuration(systemTimeUs / 1000, sb); - sb.append("\n"); + sb.append(" p=").append(powerMaUs / 1000).append("mAms\n"); } if (numWakelocksF > 0) { @@ -7994,11 +8005,13 @@ public final class BatteryStatsImpl extends BatteryStats { TimeUtils.formatDuration(userTimeUs / 1000, sb); sb.append(" s="); TimeUtils.formatDuration(systemTimeUs / 1000, sb); + sb.append(" p=").append(powerMaUs / 1000).append("mAms"); Slog.d(TAG, sb.toString()); } u.mUserCpuTime.addCountLocked(userTimeUs); u.mSystemCpuTime.addCountLocked(systemTimeUs); + u.mCpuPower.addCountLocked(powerMaUs); // Add the cpu speeds to this UID. These are used as a ratio // for computing the power this UID used. @@ -9229,6 +9242,7 @@ public final class BatteryStatsImpl extends BatteryStats { u.mUserCpuTime.readSummaryFromParcelLocked(in); u.mSystemCpuTime.readSummaryFromParcelLocked(in); + u.mCpuPower.readSummaryFromParcelLocked(in); int NSB = in.readInt(); if (NSB > 100) { @@ -9575,6 +9589,7 @@ public final class BatteryStatsImpl extends BatteryStats { u.mUserCpuTime.writeSummaryFromParcelLocked(out); u.mSystemCpuTime.writeSummaryFromParcelLocked(out); + u.mCpuPower.writeSummaryFromParcelLocked(out); out.writeInt(u.mSpeedBins.length); for (int i = 0; i < u.mSpeedBins.length; i++) { diff --git a/core/java/com/android/internal/os/KernelUidCpuTimeReader.java b/core/java/com/android/internal/os/KernelUidCpuTimeReader.java index 41efd2c..e2d366a 100644 --- a/core/java/com/android/internal/os/KernelUidCpuTimeReader.java +++ b/core/java/com/android/internal/os/KernelUidCpuTimeReader.java @@ -30,7 +30,7 @@ import java.io.IOException; /** * Reads /proc/uid_cputime/show_uid_stat which has the line format: * - * uid: user_time_micro_seconds system_time_micro_seconds + * uid: user_time_micro_seconds system_time_micro_seconds power_in_milli-amp-micro_seconds * * This provides the time a UID's processes spent executing in user-space and kernel-space. * The file contains a monotonically increasing count of time for a single boot. This class @@ -46,11 +46,18 @@ public class KernelUidCpuTimeReader { * Callback interface for processing each line of the proc file. */ public interface Callback { - void onUidCpuTime(int uid, long userTimeUs, long systemTimeUs); + /** + * @param uid UID of the app + * @param userTimeUs time spent executing in user space in microseconds + * @param systemTimeUs time spent executing in kernel space in microseconds + * @param powerMaUs power consumed executing, in milli-ampere microseconds + */ + void onUidCpuTime(int uid, long userTimeUs, long systemTimeUs, long powerMaUs); } private SparseLongArray mLastUserTimeUs = new SparseLongArray(); private SparseLongArray mLastSystemTimeUs = new SparseLongArray(); + private SparseLongArray mLastPowerMaUs = new SparseLongArray(); private long mLastTimeReadUs = 0; /** @@ -70,50 +77,60 @@ public class KernelUidCpuTimeReader { final int uid = Integer.parseInt(uidStr.substring(0, uidStr.length() - 1), 10); final long userTimeUs = Long.parseLong(splitter.next(), 10); final long systemTimeUs = Long.parseLong(splitter.next(), 10); + final long powerMaUs = Long.parseLong(splitter.next(), 10) / 1000; if (callback != null) { long userTimeDeltaUs = userTimeUs; long systemTimeDeltaUs = systemTimeUs; + long powerDeltaMaUs = powerMaUs; int index = mLastUserTimeUs.indexOfKey(uid); if (index >= 0) { userTimeDeltaUs -= mLastUserTimeUs.valueAt(index); systemTimeDeltaUs -= mLastSystemTimeUs.valueAt(index); + powerDeltaMaUs -= mLastPowerMaUs.valueAt(index); final long timeDiffUs = nowUs - mLastTimeReadUs; - if (userTimeDeltaUs < 0 || systemTimeDeltaUs < 0 || + if (userTimeDeltaUs < 0 || systemTimeDeltaUs < 0 || powerDeltaMaUs < 0 || userTimeDeltaUs > timeDiffUs || systemTimeDeltaUs > timeDiffUs) { - StringBuilder sb = new StringBuilder("Malformed cpu data!\n"); + StringBuilder sb = new StringBuilder("Malformed cpu data for UID="); + sb.append(uid).append("!\n"); sb.append("Time between reads: "); TimeUtils.formatDuration(timeDiffUs / 1000, sb); - sb.append("ms\n"); + sb.append("\n"); sb.append("Previous times: u="); TimeUtils.formatDuration(mLastUserTimeUs.valueAt(index) / 1000, sb); - sb.append("ms s="); + sb.append(" s="); TimeUtils.formatDuration(mLastSystemTimeUs.valueAt(index) / 1000, sb); - sb.append("ms\n"); + sb.append(" p=").append(mLastPowerMaUs.valueAt(index) / 1000); + sb.append("mAms\n"); + sb.append("Current times: u="); TimeUtils.formatDuration(userTimeUs / 1000, sb); - sb.append("ms s="); + sb.append(" s="); TimeUtils.formatDuration(systemTimeUs / 1000, sb); - sb.append("ms\n"); - sb.append("Delta for UID=").append(uid).append(": u="); + sb.append(" p=").append(powerMaUs / 1000); + sb.append("mAms\n"); + sb.append("Delta: u="); TimeUtils.formatDuration(userTimeDeltaUs / 1000, sb); - sb.append("ms s="); + sb.append(" s="); TimeUtils.formatDuration(systemTimeDeltaUs / 1000, sb); - sb.append("ms"); + sb.append(" p=").append(powerDeltaMaUs / 1000).append("mAms"); Slog.wtf(TAG, sb.toString()); userTimeDeltaUs = 0; systemTimeDeltaUs = 0; + powerDeltaMaUs = 0; } } - if (userTimeDeltaUs != 0 || systemTimeDeltaUs != 0) { - callback.onUidCpuTime(uid, userTimeDeltaUs, systemTimeDeltaUs); + if (userTimeDeltaUs != 0 || systemTimeDeltaUs != 0 || powerDeltaMaUs != 0) { + callback.onUidCpuTime(uid, userTimeDeltaUs, systemTimeDeltaUs, + powerDeltaMaUs); } } mLastUserTimeUs.put(uid, userTimeUs); mLastSystemTimeUs.put(uid, systemTimeUs); + mLastPowerMaUs.put(uid, powerMaUs); } } catch (IOException e) { Slog.e(TAG, "Failed to read uid_cputime", e); diff --git a/core/java/com/android/internal/view/FloatingActionMode.java b/core/java/com/android/internal/view/FloatingActionMode.java index c869722..b2699f8 100644 --- a/core/java/com/android/internal/view/FloatingActionMode.java +++ b/core/java/com/android/internal/view/FloatingActionMode.java @@ -167,6 +167,7 @@ public class FloatingActionMode extends ActionMode { // Content rect is moving. mOriginatingView.removeCallbacks(mMovingOff); mFloatingToolbarVisibilityHelper.setMoving(true); + mFloatingToolbarVisibilityHelper.updateToolbarVisibility(); mOriginatingView.postDelayed(mMovingOff, MOVING_HIDE_DELAY); mFloatingToolbar.setContentRect(mContentRectOnWindow); @@ -174,9 +175,9 @@ public class FloatingActionMode extends ActionMode { } } else { mFloatingToolbarVisibilityHelper.setOutOfBounds(true); + mFloatingToolbarVisibilityHelper.updateToolbarVisibility(); mContentRectOnWindow.setEmpty(); } - mFloatingToolbarVisibilityHelper.updateToolbarVisibility(); mPreviousContentRectOnWindow.set(mContentRectOnWindow); } diff --git a/core/java/com/android/internal/widget/DrawingSpace.java b/core/java/com/android/internal/widget/DrawingSpace.java new file mode 100644 index 0000000..b8222db --- /dev/null +++ b/core/java/com/android/internal/widget/DrawingSpace.java @@ -0,0 +1,76 @@ +/* + * 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 com.android.internal.widget; + +import android.content.Context; +import android.util.AttributeSet; +import android.view.View; + +/** + * Implementation of {@link android.widget.Space} that uses normal View drawing + * rather than a no-op. Useful for dialogs and other places where the base View + * class is too greedy when measured with AT_MOST. + */ +public final class DrawingSpace extends View { + public DrawingSpace(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { + super(context, attrs, defStyleAttr, defStyleRes); + } + + public DrawingSpace(Context context, AttributeSet attrs, int defStyleAttr) { + this(context, attrs, defStyleAttr, 0); + } + + public DrawingSpace(Context context, AttributeSet attrs) { + this(context, attrs, 0); + } + + public DrawingSpace(Context context) { + this(context, null); + } + + /** + * Compare to: {@link View#getDefaultSize(int, int)} + * <p> + * If mode is AT_MOST, return the child size instead of the parent size + * (unless it is too big). + */ + private static int getDefaultSizeNonGreedy(int size, int measureSpec) { + int result = size; + int specMode = MeasureSpec.getMode(measureSpec); + int specSize = MeasureSpec.getSize(measureSpec); + + switch (specMode) { + case MeasureSpec.UNSPECIFIED: + result = size; + break; + case MeasureSpec.AT_MOST: + result = Math.min(size, specSize); + break; + case MeasureSpec.EXACTLY: + result = specSize; + break; + } + return result; + } + + @Override + protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { + setMeasuredDimension( + getDefaultSizeNonGreedy(getSuggestedMinimumWidth(), widthMeasureSpec), + getDefaultSizeNonGreedy(getSuggestedMinimumHeight(), heightMeasureSpec)); + } +} diff --git a/core/java/com/android/internal/widget/FloatingToolbar.java b/core/java/com/android/internal/widget/FloatingToolbar.java index 163b8ce..a6e8034 100644 --- a/core/java/com/android/internal/widget/FloatingToolbar.java +++ b/core/java/com/android/internal/widget/FloatingToolbar.java @@ -1135,7 +1135,7 @@ public final class FloatingToolbar { private final Runnable mCloseOverflow; private MenuItem.OnMenuItemClickListener mOnMenuItemClickListener; - private int mOverflowWidth = 0; + private int mOverflowWidth; private int mSuggestedHeight; /** @@ -1146,7 +1146,6 @@ public final class FloatingToolbar { */ public FloatingToolbarOverflowPanel(Context context, Runnable closeOverflow) { mCloseOverflow = Preconditions.checkNotNull(closeOverflow); - mSuggestedHeight = getScreenHeight(context); mContentView = new LinearLayout(context); mContentView.setOrientation(LinearLayout.VERTICAL); @@ -1270,7 +1269,8 @@ public final class FloatingToolbar { mListView.setLayoutParams(params); } - private int setOverflowWidth() { + private void setOverflowWidth() { + mOverflowWidth = 0; for (int i = 0; i < mListView.getAdapter().getCount(); i++) { MenuItem menuItem = (MenuItem) mListView.getAdapter().getItem(i); Preconditions.checkNotNull(menuItem); @@ -1280,7 +1280,6 @@ public final class FloatingToolbar { mOverflowWidth = Math.max( mListViewItemWidthCalculator.getMeasuredWidth(), mOverflowWidth); } - return mOverflowWidth; } private ListView createOverflowListView() { @@ -1505,18 +1504,4 @@ public final class FloatingToolbar { return context.getResources() .getDimensionPixelSize(R.dimen.floating_toolbar_menu_button_minimum_width); } - - /** - * Returns the device's screen width. - */ - private static int getScreenWidth(Context context) { - return context.getResources().getDisplayMetrics().widthPixels; - } - - /** - * Returns the device's screen height. - */ - private static int getScreenHeight(Context context) { - return context.getResources().getDisplayMetrics().heightPixels; - } } diff --git a/core/java/com/android/internal/widget/ViewPager.java b/core/java/com/android/internal/widget/ViewPager.java index e76302b..a2c4f6a 100644 --- a/core/java/com/android/internal/widget/ViewPager.java +++ b/core/java/com/android/internal/widget/ViewPager.java @@ -85,7 +85,7 @@ import java.util.Comparator; */ public class ViewPager extends ViewGroup { private static final String TAG = "ViewPager"; - private static final boolean DEBUG = true; + private static final boolean DEBUG = false; private static final int MAX_SCROLL_X = 2 << 23; private static final boolean USE_CACHE = false; |
