summaryrefslogtreecommitdiffstats
path: root/core/java
diff options
context:
space:
mode:
Diffstat (limited to 'core/java')
-rw-r--r--core/java/android/app/Notification.java7
-rw-r--r--core/java/android/app/backup/BackupAgent.java36
-rw-r--r--core/java/android/net/ConnectivityManager.java463
-rw-r--r--core/java/android/util/Patterns.java8
-rw-r--r--core/java/android/view/GLES20Canvas.java8
-rw-r--r--core/java/android/view/Surface.java1
-rw-r--r--core/java/android/view/SurfaceControl.java5
-rw-r--r--core/java/android/view/WindowManager.java54
-rw-r--r--core/java/android/view/WindowManagerPolicy.java27
-rw-r--r--core/java/android/webkit/WebView.java3
-rw-r--r--core/java/android/webkit/WebViewClassic.java12
-rw-r--r--core/java/android/widget/ListView.java18
12 files changed, 532 insertions, 110 deletions
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index 4a0ee48..ebca041 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -448,7 +448,7 @@ public class Notification implements Parcelable
* Structure to encapsulate an "action", including title and icon, that can be attached to a Notification.
* @hide
*/
- private static class Action implements Parcelable {
+ public static class Action implements Parcelable {
public int icon;
public CharSequence title;
public PendingIntent actionIntent;
@@ -500,7 +500,10 @@ public class Notification implements Parcelable
};
}
- private Action[] actions;
+ /**
+ * @hide
+ */
+ public Action[] actions;
/**
* Constructs a Notification object with default values.
diff --git a/core/java/android/app/backup/BackupAgent.java b/core/java/android/app/backup/BackupAgent.java
index b678df7..44aa06f 100644
--- a/core/java/android/app/backup/BackupAgent.java
+++ b/core/java/android/app/backup/BackupAgent.java
@@ -24,6 +24,7 @@ import android.content.pm.ApplicationInfo;
import android.os.Binder;
import android.os.IBinder;
import android.os.ParcelFileDescriptor;
+import android.os.Process;
import android.os.RemoteException;
import android.util.Log;
@@ -227,7 +228,6 @@ public abstract class BackupAgent extends ContextWrapper {
String libDir = (appInfo.nativeLibraryDir != null)
? new File(appInfo.nativeLibraryDir).getCanonicalPath()
: null;
- String externalFilesDir = getExternalFilesDir(null).getCanonicalPath();
// Filters, the scan queue, and the set of resulting entities
HashSet<String> filterSet = new HashSet<String>();
@@ -259,8 +259,17 @@ public abstract class BackupAgent extends ContextWrapper {
// getExternalFilesDir() location associated with this app. Technically there should
// not be any files here if the app does not properly have permission to access
// external storage, but edge cases happen. fullBackupFileTree() catches
- // IOExceptions and similar, and treats them as non-fatal, so we rely on that here.
- fullBackupFileTree(packageName, FullBackup.MANAGED_EXTERNAL_TREE_TOKEN, externalFilesDir, null, data);
+ // IOExceptions and similar, and treats them as non-fatal, so we rely on that; and
+ // we know a priori that processes running as the system UID are not permitted to
+ // access external storage, so we check for that as well to avoid nastygrams in
+ // the log.
+ if (Process.myUid() != Process.SYSTEM_UID) {
+ File efLocation = getExternalFilesDir(null);
+ if (efLocation != null) {
+ fullBackupFileTree(packageName, FullBackup.MANAGED_EXTERNAL_TREE_TOKEN,
+ efLocation.getCanonicalPath(), null, data);
+ }
+ }
}
/**
@@ -281,7 +290,7 @@ public abstract class BackupAgent extends ContextWrapper {
String spDir;
String cacheDir;
String libDir;
- String efDir;
+ String efDir = null;
String filePath;
ApplicationInfo appInfo = getApplicationInfo();
@@ -295,7 +304,14 @@ public abstract class BackupAgent extends ContextWrapper {
libDir = (appInfo.nativeLibraryDir == null)
? null
: new File(appInfo.nativeLibraryDir).getCanonicalPath();
- efDir = getExternalFilesDir(null).getCanonicalPath();
+
+ // may or may not have external files access to attempt backup/restore there
+ if (Process.myUid() != Process.SYSTEM_UID) {
+ File efLocation = getExternalFilesDir(null);
+ if (efLocation != null) {
+ efDir = efLocation.getCanonicalPath();
+ }
+ }
// Now figure out which well-defined tree the file is placed in, working from
// most to least specific. We also specifically exclude the lib and cache dirs.
@@ -324,7 +340,7 @@ public abstract class BackupAgent extends ContextWrapper {
} else if (filePath.startsWith(mainDir)) {
domain = FullBackup.ROOT_TREE_TOKEN;
rootpath = mainDir;
- } else if (filePath.startsWith(efDir)) {
+ } else if ((efDir != null) && filePath.startsWith(efDir)) {
domain = FullBackup.MANAGED_EXTERNAL_TREE_TOKEN;
rootpath = efDir;
} else {
@@ -451,7 +467,13 @@ public abstract class BackupAgent extends ContextWrapper {
} else if (domain.equals(FullBackup.CACHE_TREE_TOKEN)) {
basePath = getCacheDir().getCanonicalPath();
} else if (domain.equals(FullBackup.MANAGED_EXTERNAL_TREE_TOKEN)) {
- basePath = getExternalFilesDir(null).getCanonicalPath();
+ // make sure we can try to restore here before proceeding
+ if (Process.myUid() != Process.SYSTEM_UID) {
+ File efLocation = getExternalFilesDir(null);
+ if (efLocation != null) {
+ basePath = getExternalFilesDir(null).getCanonicalPath();
+ }
+ }
} else {
// Not a supported location
Log.i(TAG, "Data restored from non-app domain " + domain + ", ignoring");
diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java
index 000c56c..3a04c27 100644
--- a/core/java/android/net/ConnectivityManager.java
+++ b/core/java/android/net/ConnectivityManager.java
@@ -62,7 +62,7 @@ public class ConnectivityManager {
* NetworkInfo for the new network is also passed as an extra. This lets
* any receivers of the broadcast know that they should not necessarily
* tell the user that no data traffic will be possible. Instead, the
- * reciever should expect another broadcast soon, indicating either that
+ * receiver should expect another broadcast soon, indicating either that
* the failover attempt succeeded (and so there is still overall data
* connectivity), or that the failover attempt failed, meaning that all
* connectivity has been lost.
@@ -70,6 +70,7 @@ public class ConnectivityManager {
* For a disconnect event, the boolean extra EXTRA_NO_CONNECTIVITY
* is set to {@code true} if there are no connected networks at all.
*/
+ @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
public static final String CONNECTIVITY_ACTION = "android.net.conn.CONNECTIVITY_CHANGE";
/**
@@ -78,6 +79,7 @@ public class ConnectivityManager {
*
* @hide
*/
+ @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
public static final String CONNECTIVITY_ACTION_IMMEDIATE =
"android.net.conn.CONNECTIVITY_CHANGE_IMMEDIATE";
@@ -149,8 +151,8 @@ public class ConnectivityManager {
/**
* Broadcast action to indicate the change of data activity status
* (idle or active) on a network in a recent period.
- * The network becomes active when data transimission is started, or
- * idle if there is no data transimition for a period of time.
+ * The network becomes active when data transmission is started, or
+ * idle if there is no data transmission for a period of time.
* {@hide}
*/
@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
@@ -198,32 +200,42 @@ public class ConnectivityManager {
* the network and it's condition.
* @hide
*/
+ @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
public static final String INET_CONDITION_ACTION =
"android.net.conn.INET_CONDITION_ACTION";
/**
- * Broadcast Action: A tetherable connection has come or gone
- * TODO - finish the doc
+ * Broadcast Action: A tetherable connection has come or gone.
+ * Uses {@code ConnectivityManager.EXTRA_AVAILABLE_TETHER},
+ * {@code ConnectivityManager.EXTRA_ACTIVE_TETHER} and
+ * {@code ConnectivityManager.EXTRA_ERRORED_TETHER} to indicate
+ * the current state of tethering. Each include a list of
+ * interface names in that state (may be empty).
* @hide
*/
+ @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
public static final String ACTION_TETHER_STATE_CHANGED =
"android.net.conn.TETHER_STATE_CHANGED";
/**
* @hide
- * gives a String[]
+ * gives a String[] listing all the interfaces configured for
+ * tethering and currently available for tethering.
*/
public static final String EXTRA_AVAILABLE_TETHER = "availableArray";
/**
* @hide
- * gives a String[]
+ * gives a String[] listing all the interfaces currently tethered
+ * (ie, has dhcp support and packets potentially forwarded/NATed)
*/
public static final String EXTRA_ACTIVE_TETHER = "activeArray";
/**
* @hide
- * gives a String[]
+ * gives a String[] listing all the interfaces we tried to tether and
+ * failed. Use {@link #getLastTetherError} to find the error code
+ * for any interfaces listed here.
*/
public static final String EXTRA_ERRORED_TETHER = "erroredArray";
@@ -233,6 +245,7 @@ public class ConnectivityManager {
* notification.
* @hide
*/
+ @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
public static final String ACTION_CAPTIVE_PORTAL_TEST_COMPLETED =
"android.net.conn.CAPTIVE_PORTAL_TEST_COMPLETED";
/**
@@ -243,61 +256,63 @@ public class ConnectivityManager {
public static final String EXTRA_IS_CAPTIVE_PORTAL = "captivePortal";
/**
- * The absence of APN..
+ * The absence of a connection type.
* @hide
*/
public static final int TYPE_NONE = -1;
/**
- * The Default Mobile data connection. When active, all data traffic
- * will use this connection by default.
+ * The Mobile data connection. When active, all data traffic
+ * will use this network type's interface by default
+ * (it has a default route)
*/
public static final int TYPE_MOBILE = 0;
/**
- * The Default WIFI data connection. When active, all data traffic
- * will use this connection by default.
+ * The WIFI data connection. When active, all data traffic
+ * will use this network type's interface by default
+ * (it has a default route).
*/
public static final int TYPE_WIFI = 1;
/**
- * An MMS-specific Mobile data connection. This connection may be the
- * same as {@link #TYPE_MOBILE} but it may be different. This is used
- * by applications needing to talk to the carrier's Multimedia Messaging
- * Service servers. It may coexist with default data connections.
+ * An MMS-specific Mobile data connection. This network type may use the
+ * same network interface as {@link #TYPE_MOBILE} or it may use a different
+ * one. This is used by applications needing to talk to the carrier's
+ * Multimedia Messaging Service servers.
*/
public static final int TYPE_MOBILE_MMS = 2;
/**
- * A SUPL-specific Mobile data connection. This connection may be the
- * same as {@link #TYPE_MOBILE} but it may be different. This is used
- * by applications needing to talk to the carrier's Secure User Plane
- * Location servers for help locating the device. It may coexist with
- * default data connections.
+ * A SUPL-specific Mobile data connection. This network type may use the
+ * same network interface as {@link #TYPE_MOBILE} or it may use a different
+ * one. This is used by applications needing to talk to the carrier's
+ * Secure User Plane Location servers for help locating the device.
*/
public static final int TYPE_MOBILE_SUPL = 3;
/**
- * A DUN-specific Mobile data connection. This connection may be the
- * same as {@link #TYPE_MOBILE} but it may be different. This is used
- * by applicaitons performing a Dial Up Networking bridge so that
- * the carrier is aware of DUN traffic. It may coexist with default data
- * connections.
+ * A DUN-specific Mobile data connection. This network type may use the
+ * same network interface as {@link #TYPE_MOBILE} or it may use a different
+ * one. This is sometimes by the system when setting up an upstream connection
+ * for tethering so that the carrier is aware of DUN traffic.
*/
public static final int TYPE_MOBILE_DUN = 4;
/**
- * A High Priority Mobile data connection. This connection is typically
- * the same as {@link #TYPE_MOBILE} but the routing setup is different.
- * Only requesting processes will have access to the Mobile DNS servers
- * and only IP's explicitly requested via {@link #requestRouteToHost}
- * will route over this interface if a default route exists.
+ * A High Priority Mobile data connection. This network type uses the
+ * same network interface as {@link #TYPE_MOBILE} but the routing setup
+ * is different. Only requesting processes will have access to the
+ * Mobile DNS servers and only IP's explicitly requested via {@link #requestRouteToHost}
+ * will route over this interface if no default route exists.
*/
public static final int TYPE_MOBILE_HIPRI = 5;
/**
- * The Default WiMAX data connection. When active, all data traffic
- * will use this connection by default.
+ * The WiMAX data connection. When active, all data traffic
+ * will use this network type's interface by default
+ * (it has a default route).
*/
public static final int TYPE_WIMAX = 6;
/**
- * The Default Bluetooth data connection. When active, all data traffic
- * will use this connection by default.
+ * The Bluetooth data connection. When active, all data traffic
+ * will use this network type's interface by default
+ * (it has a default route).
*/
public static final int TYPE_BLUETOOTH = 7;
@@ -307,25 +322,26 @@ public class ConnectivityManager {
public static final int TYPE_DUMMY = 8;
/**
- * The Default Ethernet data connection. When active, all data traffic
- * will use this connection by default.
+ * The Ethernet data connection. When active, all data traffic
+ * will use this network type's interface by default
+ * (it has a default route).
*/
public static final int TYPE_ETHERNET = 9;
/**
- * Over the air Adminstration.
+ * Over the air Administration.
* {@hide}
*/
public static final int TYPE_MOBILE_FOTA = 10;
/**
- * IP Multimedia Subsystem
+ * IP Multimedia Subsystem.
* {@hide}
*/
public static final int TYPE_MOBILE_IMS = 11;
/**
- * Carrier Branded Services
+ * Carrier Branded Services.
* {@hide}
*/
public static final int TYPE_MOBILE_CBS = 12;
@@ -349,7 +365,7 @@ public class ConnectivityManager {
*
* @deprecated Since we support so many more networks now, the single
* network default network preference can't really express
- * the heirarchy. Instead, the default is defined by the
+ * the hierarchy. Instead, the default is defined by the
* networkAttributes in config.xml. You can determine
* the current value by calling {@link #getNetworkPreference()}
* from an App.
@@ -359,7 +375,11 @@ public class ConnectivityManager {
/**
* Default value for {@link Settings.Global#CONNECTIVITY_CHANGE_DELAY} in
- * milliseconds.
+ * milliseconds. This was introduced because IPv6 routes seem to take a
+ * moment to settle - trying network activity before the routes are adjusted
+ * can lead to packets using the wrong interface or having the wrong IP address.
+ * This delay is a bit crude, but in the future hopefully we will have kernel
+ * notifications letting us know when it's safe to use the new network.
*
* @hide
*/
@@ -367,11 +387,23 @@ public class ConnectivityManager {
private final IConnectivityManager mService;
+ /**
+ * Tests if a given integer represents a valid network type.
+ * @param networkType the type to be tested
+ * @return a boolean. {@code true} if the type is valid, else {@code false}
+ */
public static boolean isNetworkTypeValid(int networkType) {
return networkType >= 0 && networkType <= MAX_NETWORK_TYPE;
}
- /** {@hide} */
+ /**
+ * Returns a non-localized string representing a given network type.
+ * ONLY used for debugging output.
+ * @param type the type needing naming
+ * @return a String for the given type, or a string version of the type ("87")
+ * if no name is known.
+ * {@hide}
+ */
public static String getNetworkTypeName(int type) {
switch (type) {
case TYPE_MOBILE:
@@ -407,7 +439,13 @@ public class ConnectivityManager {
}
}
- /** {@hide} */
+ /**
+ * Checks if a given type uses the cellular data connection.
+ * This should be replaced in the future by a network property.
+ * @param networkType the type to check
+ * @return a boolean - {@code true} if uses cellular network, else {@code false}
+ * {@hide}
+ */
public static boolean isNetworkTypeMobile(int networkType) {
switch (networkType) {
case TYPE_MOBILE:
@@ -424,6 +462,17 @@ public class ConnectivityManager {
}
}
+ /**
+ * Specifies the preferred network type. When the device has more
+ * than one type available the preferred network type will be used.
+ * Note that this made sense when we only had 2 network types,
+ * but with more and more default networks we need an array to list
+ * their ordering. This will be deprecated soon.
+ *
+ * @param preference the network type to prefer over all others. It is
+ * unspecified what happens to the old preferred network in the
+ * overall ordering.
+ */
public void setNetworkPreference(int preference) {
try {
mService.setNetworkPreference(preference);
@@ -431,6 +480,17 @@ public class ConnectivityManager {
}
}
+ /**
+ * Retrieves the current preferred network type.
+ * Note that this made sense when we only had 2 network types,
+ * but with more and more default networks we need an array to list
+ * their ordering. This will be deprecated soon.
+ *
+ * @return an integer representing the preferred network type
+ *
+ * <p>This method requires the caller to hold the permission
+ * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
+ */
public int getNetworkPreference() {
try {
return mService.getNetworkPreference();
@@ -440,11 +500,16 @@ public class ConnectivityManager {
}
/**
- * Returns details about the currently active data network. When connected,
- * this network is the default route for outgoing connections. You should
- * always check {@link NetworkInfo#isConnected()} before initiating network
- * traffic. This may return {@code null} when no networks are available.
- * <p>This method requires the caller to hold the permission
+ * Returns details about the currently active default data network. When
+ * connected, this network is the default route for outgoing connections.
+ * You should always check {@link NetworkInfo#isConnected()} before initiating
+ * network traffic. This may return {@code null} when there is no default
+ * network.
+ *
+ * @return a {@link NetworkInfo} object for the current default network
+ * or {@code null} if no network default network is currently active
+ *
+ * <p>This method requires the call to hold the permission
* {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
*/
public NetworkInfo getActiveNetworkInfo() {
@@ -455,7 +520,19 @@ public class ConnectivityManager {
}
}
- /** {@hide} */
+ /**
+ * Returns details about the currently active default data network
+ * for a given uid. This is for internal use only to avoid spying
+ * other apps.
+ *
+ * @return a {@link NetworkInfo} object for the current default network
+ * for the given uid or {@code null} if no default network is
+ * available for the specified uid.
+ *
+ * <p>This method requires the caller to hold the permission
+ * {@link android.Manifest.permission#CONNECTIVITY_INTERNAL}
+ * {@hide}
+ */
public NetworkInfo getActiveNetworkInfoForUid(int uid) {
try {
return mService.getActiveNetworkInfoForUid(uid);
@@ -464,6 +541,19 @@ public class ConnectivityManager {
}
}
+ /**
+ * Returns connection status information about a particular
+ * network type.
+ *
+ * @param networkType integer specifying which networkType in
+ * which you're interested.
+ * @return a {@link NetworkInfo} object for the requested
+ * network type or {@code null} if the type is not
+ * supported by the device.
+ *
+ * <p>This method requires the call to hold the permission
+ * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
+ */
public NetworkInfo getNetworkInfo(int networkType) {
try {
return mService.getNetworkInfo(networkType);
@@ -472,6 +562,16 @@ public class ConnectivityManager {
}
}
+ /**
+ * Returns connection status information about all network
+ * types supported by the device.
+ *
+ * @return an array of {@link NetworkInfo} objects. Check each
+ * {@link NetworkInfo#getType} for which type each applies.
+ *
+ * <p>This method requires the call to hold the permission
+ * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
+ */
public NetworkInfo[] getAllNetworkInfo() {
try {
return mService.getAllNetworkInfo();
@@ -480,7 +580,17 @@ public class ConnectivityManager {
}
}
- /** {@hide} */
+ /**
+ * Returns the IP information for the current default network.
+ *
+ * @return a {@link LinkProperties} object describing the IP info
+ * for the current default network, or {@code null} if there
+ * is no current default network.
+ *
+ * <p>This method requires the call to hold the permission
+ * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
+ * {@hide}
+ */
public LinkProperties getActiveLinkProperties() {
try {
return mService.getActiveLinkProperties();
@@ -489,7 +599,18 @@ public class ConnectivityManager {
}
}
- /** {@hide} */
+ /**
+ * Returns the IP information for a given network type.
+ *
+ * @param networkType the network type of interest.
+ * @return a {@link LinkProperties} object describing the IP info
+ * for the given networkType, or {@code null} if there is
+ * no current default network.
+ *
+ * <p>This method requires the call to hold the permission
+ * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
+ * {@hide}
+ */
public LinkProperties getLinkProperties(int networkType) {
try {
return mService.getLinkProperties(networkType);
@@ -498,7 +619,18 @@ public class ConnectivityManager {
}
}
- /** {@hide} */
+ /**
+ * Tells each network type to set its radio power state as directed.
+ *
+ * @param turnOn a boolean, {@code true} to turn the radios on,
+ * {@code false} to turn them off.
+ * @return a boolean, {@code true} indicating success. All network types
+ * will be tried, even if some fail.
+ *
+ * <p>This method requires the call to hold the permission
+ * {@link android.Manifest.permission#CHANGE_NETWORK_STATE}.
+ * {@hide}
+ */
public boolean setRadios(boolean turnOn) {
try {
return mService.setRadios(turnOn);
@@ -507,7 +639,18 @@ public class ConnectivityManager {
}
}
- /** {@hide} */
+ /**
+ * Tells a given networkType to set its radio power state as directed.
+ *
+ * @param networkType the int networkType of interest.
+ * @param turnOn a boolean, {@code true} to turn the radio on,
+ * {@code} false to turn it off.
+ * @return a boolean, {@code true} indicating success.
+ *
+ * <p>This method requires the call to hold the permission
+ * {@link android.Manifest.permission#CHANGE_NETWORK_STATE}.
+ * {@hide}
+ */
public boolean setRadio(int networkType, boolean turnOn) {
try {
return mService.setRadio(networkType, turnOn);
@@ -642,6 +785,9 @@ public class ConnectivityManager {
* network is active. Quota status can change rapidly, so these values
* shouldn't be cached.
*
+ * <p>This method requires the call to hold the permission
+ * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
+ *
* @hide
*/
public NetworkQuotaInfo getActiveNetworkQuotaInfo() {
@@ -656,6 +802,9 @@ public class ConnectivityManager {
* Gets the value of the setting for enabling Mobile data.
*
* @return Whether mobile data is enabled.
+ *
+ * <p>This method requires the call to hold the permission
+ * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
* @hide
*/
public boolean getMobileDataEnabled() {
@@ -669,8 +818,8 @@ public class ConnectivityManager {
/**
* Sets the persisted value for enabling/disabling Mobile data.
*
- * @param enabled Whether the mobile data connection should be
- * used or not.
+ * @param enabled Whether the user wants the mobile data connection used
+ * or not.
* @hide
*/
public void setMobileDataEnabled(boolean enabled) {
@@ -693,6 +842,13 @@ public class ConnectivityManager {
}
/**
+ * Get the set of tetherable, available interfaces. This list is limited by
+ * device configuration and current interface existence.
+ *
+ * @return an array of 0 or more Strings of tetherable interface names.
+ *
+ * <p>This method requires the call to hold the permission
+ * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
* {@hide}
*/
public String[] getTetherableIfaces() {
@@ -704,6 +860,12 @@ public class ConnectivityManager {
}
/**
+ * Get the set of tethered interfaces.
+ *
+ * @return an array of 0 or more String of currently tethered interface names.
+ *
+ * <p>This method requires the call to hold the permission
+ * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
* {@hide}
*/
public String[] getTetheredIfaces() {
@@ -715,6 +877,18 @@ public class ConnectivityManager {
}
/**
+ * Get the set of interface names which attempted to tether but
+ * failed. Re-attempting to tether may cause them to reset to the Tethered
+ * state. Alternatively, causing the interface to be destroyed and recreated
+ * may cause them to reset to the available state.
+ * {@link ConnectivityManager#getLastTetherError} can be used to get more
+ * information on the cause of the errors.
+ *
+ * @return an array of 0 or more String indicating the interface names
+ * which failed to tether.
+ *
+ * <p>This method requires the call to hold the permission
+ * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
* {@hide}
*/
public String[] getTetheringErroredIfaces() {
@@ -726,7 +900,19 @@ public class ConnectivityManager {
}
/**
- * @return error A TETHER_ERROR value indicating success or failure type
+ * Attempt to tether the named interface. This will setup a dhcp server
+ * on the interface, forward and NAT IP packets and forward DNS requests
+ * to the best active upstream network interface. Note that if no upstream
+ * IP network interface is available, dhcp will still run and traffic will be
+ * allowed between the tethered devices and this device, though upstream net
+ * access will of course fail until an upstream network interface becomes
+ * active.
+ *
+ * @param iface the interface name to tether.
+ * @return error a {@code TETHER_ERROR} value indicating success or failure type
+ *
+ * <p>This method requires the call to hold the permission
+ * {@link android.Manifest.permission#CHANGE_NETWORK_STATE}.
* {@hide}
*/
public int tether(String iface) {
@@ -738,7 +924,13 @@ public class ConnectivityManager {
}
/**
- * @return error A TETHER_ERROR value indicating success or failure type
+ * Stop tethering the named interface.
+ *
+ * @param iface the interface name to untether.
+ * @return error a {@code TETHER_ERROR} value indicating success or failure type
+ *
+ * <p>This method requires the call to hold the permission
+ * {@link android.Manifest.permission#CHANGE_NETWORK_STATE}.
* {@hide}
*/
public int untether(String iface) {
@@ -750,6 +942,14 @@ public class ConnectivityManager {
}
/**
+ * Check if the device allows for tethering. It may be disabled via
+ * {@code ro.tether.denied} system property, {@link Settings#TETHER_SUPPORTED} or
+ * due to device configuration.
+ *
+ * @return a boolean - {@code true} indicating Tethering is supported.
+ *
+ * <p>This method requires the call to hold the permission
+ * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
* {@hide}
*/
public boolean isTetheringSupported() {
@@ -761,6 +961,15 @@ public class ConnectivityManager {
}
/**
+ * Get the list of regular expressions that define any tetherable
+ * USB network interfaces. If USB tethering is not supported by the
+ * device, this list should be empty.
+ *
+ * @return an array of 0 or more regular expression Strings defining
+ * what interfaces are considered tetherable usb interfaces.
+ *
+ * <p>This method requires the call to hold the permission
+ * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
* {@hide}
*/
public String[] getTetherableUsbRegexs() {
@@ -772,6 +981,15 @@ public class ConnectivityManager {
}
/**
+ * Get the list of regular expressions that define any tetherable
+ * Wifi network interfaces. If Wifi tethering is not supported by the
+ * device, this list should be empty.
+ *
+ * @return an array of 0 or more regular expression Strings defining
+ * what interfaces are considered tetherable wifi interfaces.
+ *
+ * <p>This method requires the call to hold the permission
+ * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
* {@hide}
*/
public String[] getTetherableWifiRegexs() {
@@ -783,6 +1001,15 @@ public class ConnectivityManager {
}
/**
+ * Get the list of regular expressions that define any tetherable
+ * Bluetooth network interfaces. If Bluetooth tethering is not supported by the
+ * device, this list should be empty.
+ *
+ * @return an array of 0 or more regular expression Strings defining
+ * what interfaces are considered tetherable bluetooth interfaces.
+ *
+ * <p>This method requires the call to hold the permission
+ * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
* {@hide}
*/
public String[] getTetherableBluetoothRegexs() {
@@ -794,6 +1021,17 @@ public class ConnectivityManager {
}
/**
+ * Attempt to both alter the mode of USB and Tethering of USB. A
+ * utility method to deal with some of the complexity of USB - will
+ * attempt to switch to Rndis and subsequently tether the resulting
+ * interface on {@code true} or turn off tethering and switch off
+ * Rndis on {@code false}.
+ *
+ * @param enable a boolean - {@code true} to enable tethering
+ * @return error a {@code TETHER_ERROR} value indicating success or failure type
+ *
+ * <p>This method requires the call to hold the permission
+ * {@link android.Manifest.permission#CHANGE_NETWORK_STATE}.
* {@hide}
*/
public int setUsbTethering(boolean enable) {
@@ -828,9 +1066,15 @@ public class ConnectivityManager {
public static final int TETHER_ERROR_IFACE_CFG_ERROR = 10;
/**
- * @param iface The name of the interface we're interested in
+ * Get a more detailed error code after a Tethering or Untethering
+ * request asynchronously failed.
+ *
+ * @param iface The name of the interface of interest
* @return error The error code of the last error tethering or untethering the named
* interface
+ *
+ * <p>This method requires the call to hold the permission
+ * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
* {@hide}
*/
public int getLastTetherError(String iface) {
@@ -842,9 +1086,16 @@ public class ConnectivityManager {
}
/**
- * Ensure the device stays awake until we connect with the next network
- * @param forWhome The name of the network going down for logging purposes
+ * Try to ensure the device stays awake until we connect with the next network.
+ * Actually just holds a wakelock for a number of seconds while we try to connect
+ * to any default networks. This will expire if the timeout passes or if we connect
+ * to a default after this is called. For internal use only.
+ *
+ * @param forWhom the name of the network going down for logging purposes
* @return {@code true} on success, {@code false} on failure
+ *
+ * <p>This method requires the call to hold the permission
+ * {@link android.Manifest.permission#CONNECTIVITY_INTERNAL}.
* {@hide}
*/
public boolean requestNetworkTransitionWakelock(String forWhom) {
@@ -857,8 +1108,14 @@ public class ConnectivityManager {
}
/**
+ * Report network connectivity status. This is currently used only
+ * to alter status bar UI.
+ *
* @param networkType The type of network you want to report on
* @param percentage The quality of the connection 0 is bad, 100 is good
+ *
+ * <p>This method requires the call to hold the permission
+ * {@link android.Manifest.permission#STATUS_BAR}.
* {@hide}
*/
public void reportInetCondition(int networkType, int percentage) {
@@ -869,7 +1126,16 @@ public class ConnectivityManager {
}
/**
- * @param proxyProperties The definition for the new global http proxy
+ * Set a network-independent global http proxy. This is not normally what you want
+ * for typical HTTP proxies - they are general network dependent. However if you're
+ * doing something unusual like general internal filtering this may be useful. On
+ * a private network where the proxy is not accessible, you may break HTTP using this.
+ *
+ * @param proxyProperties The a {@link ProxyProperites} object defining the new global
+ * HTTP proxy. A {@code null} value will clear the global HTTP proxy.
+ *
+ * <p>This method requires the call to hold the permission
+ * {@link android.Manifest.permission#CHANGE_NETWORK_STATE}.
* {@hide}
*/
public void setGlobalProxy(ProxyProperties p) {
@@ -880,7 +1146,13 @@ public class ConnectivityManager {
}
/**
- * @return proxyProperties for the current global proxy
+ * Retrieve any network-independent global HTTP proxy.
+ *
+ * @return {@link ProxyProperties} for the current global HTTP proxy or {@code null}
+ * if no global HTTP proxy is set.
+ *
+ * <p>This method requires the call to hold the permission
+ * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
* {@hide}
*/
public ProxyProperties getGlobalProxy() {
@@ -892,7 +1164,14 @@ public class ConnectivityManager {
}
/**
- * @return proxyProperties for the current proxy (global if set, network specific if not)
+ * Get the HTTP proxy settings for the current default network. Note that
+ * if a global proxy is set, it will override any per-network setting.
+ *
+ * @return the {@link ProxyProperties} for the current HTTP proxy, or {@code null} if no
+ * HTTP proxy is active.
+ *
+ * <p>This method requires the call to hold the permission
+ * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
* {@hide}
*/
public ProxyProperties getProxy() {
@@ -904,8 +1183,15 @@ public class ConnectivityManager {
}
/**
+ * Sets a secondary requirement bit for the given networkType.
+ * This requirement bit is generally under the control of the carrier
+ * or its agents and is not directly controlled by the user.
+ *
* @param networkType The network who's dependence has changed
- * @param met Boolean - true if network use is ok, false if not
+ * @param met Boolean - true if network use is OK, false if not
+ *
+ * <p>This method requires the call to hold the permission
+ * {@link android.Manifest.permission#CONNECTIVITY_INTERNAL}.
* {@hide}
*/
public void setDataDependency(int networkType, boolean met) {
@@ -919,11 +1205,15 @@ public class ConnectivityManager {
* Returns true if the hardware supports the given network type
* else it returns false. This doesn't indicate we have coverage
* or are authorized onto a network, just whether or not the
- * hardware supports it. For example a gsm phone without a sim
- * should still return true for mobile data, but a wifi only tablet
- * would return false.
- * @param networkType The nework type we'd like to check
- * @return true if supported, else false
+ * hardware supports it. For example a GSM phone without a SIM
+ * should still return {@code true} for mobile data, but a wifi only
+ * tablet would return {@code false}.
+ *
+ * @param networkType The network type we'd like to check
+ * @return {@code true} if supported, else {@code false}
+ *
+ * <p>This method requires the call to hold the permission
+ * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
* @hide
*/
public boolean isNetworkSupported(int networkType) {
@@ -936,9 +1226,16 @@ public class ConnectivityManager {
/**
* Returns if the currently active data network is metered. A network is
* classified as metered when the user is sensitive to heavy data usage on
- * that connection. You should check this before doing large data transfers,
- * and warn the user or delay the operation until another network is
- * available.
+ * that connection due to monetary costs, data limitations or
+ * battery/performance issues. You should check this before doing large
+ * data transfers, and warn the user or delay the operation until another
+ * network is available.
+ *
+ * @return {@code true} if large transfers should be avoided, otherwise
+ * {@code false}.
+ *
+ * <p>This method requires the call to hold the permission
+ * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
*/
public boolean isActiveNetworkMetered() {
try {
@@ -948,7 +1245,15 @@ public class ConnectivityManager {
}
}
- /** {@hide} */
+ /**
+ * If the LockdownVpn mechanism is enabled, updates the vpn
+ * with a reload of its profile.
+ *
+ * @return a boolean with {@code} indicating success
+ *
+ * <p>This method can only be called by the system UID
+ * {@hide}
+ */
public boolean updateLockdownVpn() {
try {
return mService.updateLockdownVpn();
@@ -958,6 +1263,14 @@ public class ConnectivityManager {
}
/**
+ * Signal that the captive portal check on the indicated network
+ * is complete and we can turn the network on for general use.
+ *
+ * @param info the {@link NetworkInfo} object for the networkType
+ * in question.
+ *
+ * <p>This method requires the call to hold the permission
+ * {@link android.Manifest.permission#CONNECTIVITY_INTERNAL}.
* {@hide}
*/
public void captivePortalCheckComplete(NetworkInfo info) {
diff --git a/core/java/android/util/Patterns.java b/core/java/android/util/Patterns.java
index 152827d..9522112 100644
--- a/core/java/android/util/Patterns.java
+++ b/core/java/android/util/Patterns.java
@@ -169,10 +169,10 @@ public class Patterns {
* </ul>
*/
public static final Pattern PHONE
- = Pattern.compile( // sdd = space, dot, or dash
- "(\\+[0-9]+[\\- \\.]*)?" // +<digits><sdd>*
- + "(\\([0-9]+\\)[\\- \\.]*)?" // (<digits>)<sdd>*
- + "([0-9][0-9\\- \\.][0-9\\- \\.]+[0-9])"); // <digit><digit|sdd>+<digit>
+ = Pattern.compile( // sdd = space, dot, or dash
+ "(\\+[0-9]+[\\- \\.]*)?" // +<digits><sdd>*
+ + "(\\([0-9]+\\)[\\- \\.]*)?" // (<digits>)<sdd>*
+ + "([0-9][0-9\\- \\.]+[0-9])"); // <digit><digit|sdd>+<digit>
/**
* Convenience method to take all of the non-null matching groups in a
diff --git a/core/java/android/view/GLES20Canvas.java b/core/java/android/view/GLES20Canvas.java
index 7ff8d09..6c48e43 100644
--- a/core/java/android/view/GLES20Canvas.java
+++ b/core/java/android/view/GLES20Canvas.java
@@ -497,22 +497,22 @@ class GLES20Canvas extends HardwareCanvas {
@Override
public boolean quickReject(float left, float top, float right, float bottom, EdgeType type) {
- return nQuickReject(mRenderer, left, top, right, bottom, type.nativeInt);
+ return nQuickReject(mRenderer, left, top, right, bottom);
}
private static native boolean nQuickReject(int renderer, float left, float top,
- float right, float bottom, int edge);
+ float right, float bottom);
@Override
public boolean quickReject(Path path, EdgeType type) {
path.computeBounds(mPathBounds, true);
return nQuickReject(mRenderer, mPathBounds.left, mPathBounds.top,
- mPathBounds.right, mPathBounds.bottom, type.nativeInt);
+ mPathBounds.right, mPathBounds.bottom);
}
@Override
public boolean quickReject(RectF rect, EdgeType type) {
- return nQuickReject(mRenderer, rect.left, rect.top, rect.right, rect.bottom, type.nativeInt);
+ return nQuickReject(mRenderer, rect.left, rect.top, rect.right, rect.bottom);
}
///////////////////////////////////////////////////////////////////////////
diff --git a/core/java/android/view/Surface.java b/core/java/android/view/Surface.java
index de64e14..03a9b09 100644
--- a/core/java/android/view/Surface.java
+++ b/core/java/android/view/Surface.java
@@ -75,7 +75,6 @@ public class Surface implements Parcelable {
private int mGenerationId; // incremented each time mNativeSurface changes
private final Canvas mCanvas = new CompatibleCanvas();
- private int mCanvasSaveCount; // Canvas save count at time of lockCanvas()
// The Translator for density compatibility mode. This is used for scaling
// the canvas to perform the appropriate density transformation.
diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java
index 9f50065..7ef7e2b 100644
--- a/core/java/android/view/SurfaceControl.java
+++ b/core/java/android/view/SurfaceControl.java
@@ -339,11 +339,6 @@ public class SurfaceControl {
nativeSetLayer(mNativeObject, zorder);
}
- public void setPosition(int x, int y) {
- checkNotReleased();
- nativeSetPosition(mNativeObject, (float)x, (float)y);
- }
-
public void setPosition(float x, float y) {
checkNotReleased();
nativeSetPosition(mNativeObject, x, y);
diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java
index d236561..bf330f3 100644
--- a/core/java/android/view/WindowManager.java
+++ b/core/java/android/view/WindowManager.java
@@ -1193,6 +1193,37 @@ public interface WindowManager extends ViewManager {
public float buttonBrightness = BRIGHTNESS_OVERRIDE_NONE;
/**
+ * Value for {@link #rotationAnimation} to define the animation used to
+ * specify that this window will rotate in or out following a rotation.
+ */
+ public static final int ROTATION_ANIMATION_ROTATE = 0;
+
+ /**
+ * Value for {@link #rotationAnimation} to define the animation used to
+ * specify that this window will fade in or out following a rotation.
+ */
+ public static final int ROTATION_ANIMATION_CROSSFADE = 1;
+
+ /**
+ * Value for {@link #rotationAnimation} to define the animation used to
+ * specify that this window will immediately disappear or appear following
+ * a rotation.
+ */
+ public static final int ROTATION_ANIMATION_JUMPCUT = 2;
+
+ /**
+ * Define the animation used on this window for entry or exit following
+ * a rotation. This only works if the incoming and outgoing topmost
+ * opaque windows have the #FLAG_FULLSCREEN bit set and are not covered
+ * by other windows.
+ *
+ * @see #ROTATION_ANIMATION_ROTATE
+ * @see #ROTATION_ANIMATION_CROSSFADE
+ * @see #ROTATION_ANIMATION_JUMPCUT
+ */
+ public int rotationAnimation = ROTATION_ANIMATION_ROTATE;
+
+ /**
* Identifier for this window. This will usually be filled in for
* you.
*/
@@ -1367,6 +1398,7 @@ public interface WindowManager extends ViewManager {
out.writeFloat(dimAmount);
out.writeFloat(screenBrightness);
out.writeFloat(buttonBrightness);
+ out.writeInt(rotationAnimation);
out.writeStrongBinder(token);
out.writeString(packageName);
TextUtils.writeToParcel(mTitle, out, parcelableFlags);
@@ -1408,6 +1440,7 @@ public interface WindowManager extends ViewManager {
dimAmount = in.readFloat();
screenBrightness = in.readFloat();
buttonBrightness = in.readFloat();
+ rotationAnimation = in.readInt();
token = in.readStrongBinder();
packageName = in.readString();
mTitle = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in);
@@ -1432,18 +1465,19 @@ public interface WindowManager extends ViewManager {
public static final int SOFT_INPUT_MODE_CHANGED = 1<<9;
public static final int SCREEN_ORIENTATION_CHANGED = 1<<10;
public static final int SCREEN_BRIGHTNESS_CHANGED = 1<<11;
+ public static final int ROTATION_ANIMATION_CHANGED = 1<<12;
/** {@hide} */
- public static final int BUTTON_BRIGHTNESS_CHANGED = 1<<12;
+ public static final int BUTTON_BRIGHTNESS_CHANGED = 1<<13;
/** {@hide} */
- public static final int SYSTEM_UI_VISIBILITY_CHANGED = 1<<13;
+ public static final int SYSTEM_UI_VISIBILITY_CHANGED = 1<<14;
/** {@hide} */
- public static final int SYSTEM_UI_LISTENER_CHANGED = 1<<14;
+ public static final int SYSTEM_UI_LISTENER_CHANGED = 1<<15;
/** {@hide} */
- public static final int INPUT_FEATURES_CHANGED = 1<<15;
+ public static final int INPUT_FEATURES_CHANGED = 1<<16;
/** {@hide} */
- public static final int PRIVATE_FLAGS_CHANGED = 1<<16;
+ public static final int PRIVATE_FLAGS_CHANGED = 1<<17;
/** {@hide} */
- public static final int USER_ACTIVITY_TIMEOUT_CHANGED = 1<<17;
+ public static final int USER_ACTIVITY_TIMEOUT_CHANGED = 1<<18;
/** {@hide} */
public static final int EVERYTHING_CHANGED = 0xffffffff;
@@ -1543,6 +1577,10 @@ public interface WindowManager extends ViewManager {
buttonBrightness = o.buttonBrightness;
changes |= BUTTON_BRIGHTNESS_CHANGED;
}
+ if (rotationAnimation != o.rotationAnimation) {
+ rotationAnimation = o.rotationAnimation;
+ changes |= ROTATION_ANIMATION_CHANGED;
+ }
if (screenOrientation != o.screenOrientation) {
screenOrientation = o.screenOrientation;
@@ -1645,6 +1683,10 @@ public interface WindowManager extends ViewManager {
sb.append(" bbrt=");
sb.append(buttonBrightness);
}
+ if (rotationAnimation != ROTATION_ANIMATION_ROTATE) {
+ sb.append(" rotAnim=");
+ sb.append(rotationAnimation);
+ }
if ((flags & FLAG_COMPATIBLE_WINDOW) != 0) {
sb.append(" compatible=true");
}
diff --git a/core/java/android/view/WindowManagerPolicy.java b/core/java/android/view/WindowManagerPolicy.java
index 192eded..60779ce 100644
--- a/core/java/android/view/WindowManagerPolicy.java
+++ b/core/java/android/view/WindowManagerPolicy.java
@@ -684,6 +684,31 @@ public interface WindowManagerPolicy {
public int selectAnimationLw(WindowState win, int transit);
/**
+ * Determine the animation to run for a rotation transition based on the
+ * top fullscreen windows {@link WindowManager.LayoutParams#rotationAnimation}
+ * and whether it is currently fullscreen and frontmost.
+ *
+ * @param anim The exiting animation resource id is stored in anim[0], the
+ * entering animation resource id is stored in anim[1].
+ */
+ public void selectRotationAnimationLw(int anim[]);
+
+ /**
+ * Validate whether the current top fullscreen has specified the same
+ * {@link WindowManager.LayoutParams#rotationAnimation} value as that
+ * being passed in from the previous top fullscreen window.
+ *
+ * @param exitAnimId exiting resource id from the previous window.
+ * @param enterAnimId entering resource id from the previous window.
+ * @param forceDefault For rotation animations only, if true ignore the
+ * animation values and just return false.
+ * @return true if the previous values are still valid, false if they
+ * should be replaced with the default.
+ */
+ public boolean validateRotationAnimationLw(int exitAnimId, int enterAnimId,
+ boolean forceDefault);
+
+ /**
* Create and return an animation to re-display a force hidden window.
*/
public Animation createForceHideEnterAnimation(boolean onWallpaper);
@@ -909,6 +934,7 @@ public interface WindowManagerPolicy {
* @see android.app.KeyguardManager.KeyguardLock#disableKeyguard()
* @see android.app.KeyguardManager.KeyguardLock#reenableKeyguard()
*/
+ @SuppressWarnings("javadoc")
public void enableKeyguard(boolean enabled);
/**
@@ -924,6 +950,7 @@ public interface WindowManagerPolicy {
* @param callback Callback to send the result back.
* @see android.app.KeyguardManager#exitKeyguardSecurely(android.app.KeyguardManager.OnKeyguardExitResult)
*/
+ @SuppressWarnings("javadoc")
void exitKeyguardSecurely(OnKeyguardExitResult callback);
/**
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index d0bfbe8..1321515 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -334,7 +334,8 @@ public class WebView extends AbsoluteLayout
* See {@link WebView#capturePicture} for details of the picture.
*
* @param view the WebView that owns the picture
- * @param picture the new picture
+ * @param picture the new picture. Applications targetting Jelly
+ * Bean MR2 or above will always receive a null Picture.
* @deprecated Deprecated due to internal changes.
*/
@Deprecated
diff --git a/core/java/android/webkit/WebViewClassic.java b/core/java/android/webkit/WebViewClassic.java
index 3ded1cd..19784a4 100644
--- a/core/java/android/webkit/WebViewClassic.java
+++ b/core/java/android/webkit/WebViewClassic.java
@@ -7909,7 +7909,11 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc
if (mPictureListener != null) {
// trigger picture listener for hardware layers. Software layers are
// triggered in setNewPicture
- mPictureListener.onNewPicture(getWebView(), capturePicture());
+ // TODO: Update CUR_DEVELOPMENT when appropriate JBMR2 constant is
+ // available.
+ Picture picture = mContext.getApplicationInfo().targetSdkVersion <
+ Build.VERSION_CODES.CUR_DEVELOPMENT ? capturePicture() : null;
+ mPictureListener.onNewPicture(getWebView(), picture);
}
}
@@ -7994,7 +7998,11 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc
|| mWebView.getLayerType() == View.LAYER_TYPE_SOFTWARE) {
// trigger picture listener for software layers. Hardware layers are
// triggered in pageSwapCallback
- mPictureListener.onNewPicture(getWebView(), capturePicture());
+ // TODO: Update CUR_DEVELOPMENT when appropriate JBMR2 constant is
+ // available.
+ Picture picture = mContext.getApplicationInfo().targetSdkVersion <
+ Build.VERSION_CODES.CUR_DEVELOPMENT ? capturePicture() : null;
+ mPictureListener.onNewPicture(getWebView(), picture);
}
}
}
diff --git a/core/java/android/widget/ListView.java b/core/java/android/widget/ListView.java
index 69e3177..4436fbb 100644
--- a/core/java/android/widget/ListView.java
+++ b/core/java/android/widget/ListView.java
@@ -2429,7 +2429,9 @@ public class ListView extends AbsListView {
View selectedView = getSelectedView();
int selectedPos = mSelectedPosition;
- int nextSelectedPosition = lookForSelectablePositionOnScreen(direction);
+ int nextSelectedPosition = (direction == View.FOCUS_DOWN) ?
+ lookForSelectablePosition(selectedPos + 1, true) :
+ lookForSelectablePosition(selectedPos - 1, false);
int amountToScroll = amountToScroll(direction, nextSelectedPosition);
// if we are moving focus, we may OVERRIDE the default behavior
@@ -2641,14 +2643,18 @@ public class ListView extends AbsListView {
final int listBottom = getHeight() - mListPadding.bottom;
final int listTop = mListPadding.top;
- final int numChildren = getChildCount();
+ int numChildren = getChildCount();
if (direction == View.FOCUS_DOWN) {
int indexToMakeVisible = numChildren - 1;
if (nextSelectedPosition != INVALID_POSITION) {
indexToMakeVisible = nextSelectedPosition - mFirstPosition;
}
-
+ while (numChildren <= indexToMakeVisible) {
+ // Child to view is not attached yet.
+ addViewBelow(getChildAt(numChildren - 1), mFirstPosition + numChildren - 1);
+ numChildren++;
+ }
final int positionToMakeVisible = mFirstPosition + indexToMakeVisible;
final View viewToMakeVisible = getChildAt(indexToMakeVisible);
@@ -2682,6 +2688,12 @@ public class ListView extends AbsListView {
if (nextSelectedPosition != INVALID_POSITION) {
indexToMakeVisible = nextSelectedPosition - mFirstPosition;
}
+ while (indexToMakeVisible < 0) {
+ // Child to view is not attached yet.
+ addViewAbove(getChildAt(0), mFirstPosition);
+ mFirstPosition--;
+ indexToMakeVisible = nextSelectedPosition - mFirstPosition;
+ }
final int positionToMakeVisible = mFirstPosition + indexToMakeVisible;
final View viewToMakeVisible = getChildAt(indexToMakeVisible);
int goalTop = listTop;