diff options
| -rw-r--r-- | cmds/pm/src/com/android/commands/pm/Pm.java | 2 | ||||
| -rw-r--r-- | core/java/android/net/ConnectivityManager.java | 91 | ||||
| -rw-r--r-- | core/java/android/webkit/WebSettings.java | 6 | ||||
| -rw-r--r-- | services/core/java/com/android/server/ConnectivityService.java | 56 | ||||
| -rw-r--r-- | services/core/java/com/android/server/MountService.java | 27 | ||||
| -rw-r--r-- | wifi/java/android/net/wifi/WifiManager.java | 5 |
6 files changed, 134 insertions, 53 deletions
diff --git a/cmds/pm/src/com/android/commands/pm/Pm.java b/cmds/pm/src/com/android/commands/pm/Pm.java index ce83caa..2dcd9cb 100644 --- a/cmds/pm/src/com/android/commands/pm/Pm.java +++ b/cmds/pm/src/com/android/commands/pm/Pm.java @@ -1025,6 +1025,8 @@ public final class Pm { params.installFlags |= PackageManager.INSTALL_INTERNAL; } else if (opt.equals("-d")) { params.installFlags |= PackageManager.INSTALL_ALLOW_DOWNGRADE; + } else if (opt.equals("-g")) { + params.installFlags |= PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS; } else if (opt.equals("--originating-uri")) { params.originatingUri = Uri.parse(nextOptionData()); } else if (opt.equals("--referrer")) { diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java index 12cd5f1..01334c3 100644 --- a/core/java/android/net/ConnectivityManager.java +++ b/core/java/android/net/ConnectivityManager.java @@ -2081,23 +2081,6 @@ public class ConnectivityManager { * changes. Should be extended by applications wanting notifications. */ public static class NetworkCallback { - /** @hide */ - public static final int PRECHECK = 1; - /** @hide */ - public static final int AVAILABLE = 2; - /** @hide */ - public static final int LOSING = 3; - /** @hide */ - public static final int LOST = 4; - /** @hide */ - public static final int UNAVAIL = 5; - /** @hide */ - public static final int CAP_CHANGED = 6; - /** @hide */ - public static final int PROP_CHANGED = 7; - /** @hide */ - public static final int CANCELED = 8; - /** * Called when the framework connects to a new network to evaluate whether it satisfies this * request. If evaluation succeeds, this callback may be followed by an {@link #onAvailable} @@ -2174,30 +2157,54 @@ public class ConnectivityManager { */ public void onLinkPropertiesChanged(Network network, LinkProperties linkProperties) {} + /** + * Called when the network the framework connected to for this request + * goes into {@link NetworkInfo.DetailedState.SUSPENDED}. + * This generally means that while the TCP connections are still live, + * temporarily network data fails to transfer. Specifically this is used + * on cellular networks to mask temporary outages when driving through + * a tunnel, etc. + * @hide + */ + public void onNetworkSuspended(Network network) {} + + /** + * Called when the network the framework connected to for this request + * returns from a {@link NetworkInfo.DetailedState.SUSPENDED} state. + * This should always be preceeded by a matching {@code onNetworkSuspended} + * call. + * @hide + */ + public void onNetworkResumed(Network network) {} + private NetworkRequest networkRequest; } private static final int BASE = Protocol.BASE_CONNECTIVITY_MANAGER; - /** @hide obj = pair(NetworkRequest, Network) */ - public static final int CALLBACK_PRECHECK = BASE + 1; - /** @hide obj = pair(NetworkRequest, Network) */ - public static final int CALLBACK_AVAILABLE = BASE + 2; - /** @hide obj = pair(NetworkRequest, Network), arg1 = ttl */ - public static final int CALLBACK_LOSING = BASE + 3; - /** @hide obj = pair(NetworkRequest, Network) */ - public static final int CALLBACK_LOST = BASE + 4; - /** @hide obj = NetworkRequest */ - public static final int CALLBACK_UNAVAIL = BASE + 5; - /** @hide obj = pair(NetworkRequest, Network) */ - public static final int CALLBACK_CAP_CHANGED = BASE + 6; - /** @hide obj = pair(NetworkRequest, Network) */ - public static final int CALLBACK_IP_CHANGED = BASE + 7; - /** @hide obj = NetworkRequest */ - public static final int CALLBACK_RELEASED = BASE + 8; /** @hide */ - public static final int CALLBACK_EXIT = BASE + 9; + public static final int CALLBACK_PRECHECK = BASE + 1; + /** @hide */ + public static final int CALLBACK_AVAILABLE = BASE + 2; + /** @hide arg1 = TTL */ + public static final int CALLBACK_LOSING = BASE + 3; + /** @hide */ + public static final int CALLBACK_LOST = BASE + 4; + /** @hide */ + public static final int CALLBACK_UNAVAIL = BASE + 5; + /** @hide */ + public static final int CALLBACK_CAP_CHANGED = BASE + 6; + /** @hide */ + public static final int CALLBACK_IP_CHANGED = BASE + 7; + /** @hide */ + public static final int CALLBACK_RELEASED = BASE + 8; + /** @hide */ + public static final int CALLBACK_EXIT = BASE + 9; /** @hide obj = NetworkCapabilities, arg1 = seq number */ - private static final int EXPIRE_LEGACY_REQUEST = BASE + 10; + private static final int EXPIRE_LEGACY_REQUEST = BASE + 10; + /** @hide */ + public static final int CALLBACK_SUSPENDED = BASE + 11; + /** @hide */ + public static final int CALLBACK_RESUMED = BASE + 12; private class CallbackHandler extends Handler { private final HashMap<NetworkRequest, NetworkCallback>mCallbackMap; @@ -2274,6 +2281,20 @@ public class ConnectivityManager { } break; } + case CALLBACK_SUSPENDED: { + NetworkCallback callback = getCallback(request, "SUSPENDED"); + if (callback != null) { + callback.onNetworkSuspended(network); + } + break; + } + case CALLBACK_RESUMED: { + NetworkCallback callback = getCallback(request, "RESUMED"); + if (callback != null) { + callback.onNetworkResumed(network); + } + break; + } case CALLBACK_RELEASED: { NetworkCallback callback = null; synchronized(mCallbackMap) { diff --git a/core/java/android/webkit/WebSettings.java b/core/java/android/webkit/WebSettings.java index cfa347f..f62b4cc 100644 --- a/core/java/android/webkit/WebSettings.java +++ b/core/java/android/webkit/WebSettings.java @@ -1211,6 +1211,12 @@ public abstract class WebSettings { /** * Sets the WebView's user-agent string. If the string is null or empty, * the system default value will be used. + * + * Note that starting from {@link android.os.Build.VERSION_CODES#KITKAT} Android + * version, changing the user-agent while loading a web page causes WebView + * to initiate loading once again. + * + * @param ua new user-agent string */ public abstract void setUserAgentString(String ua); diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java index 7f124dc..8ca075f 100644 --- a/services/core/java/com/android/server/ConnectivityService.java +++ b/services/core/java/com/android/server/ConnectivityService.java @@ -493,10 +493,10 @@ public class ConnectivityService extends IConnectivityManager.Stub } } - private void maybeLogBroadcast(NetworkAgentInfo nai, boolean connected, int type, + private void maybeLogBroadcast(NetworkAgentInfo nai, DetailedState state, int type, boolean isDefaultNetwork) { if (DBG) { - log("Sending " + (connected ? "connected" : "disconnected") + + log("Sending " + state + " broadcast for type " + type + " " + nai.name() + " isDefaultNetwork=" + isDefaultNetwork); } @@ -520,8 +520,8 @@ public class ConnectivityService extends IConnectivityManager.Stub // Send a broadcast if this is the first network of its type or if it's the default. final boolean isDefaultNetwork = isDefaultNetwork(nai); if (list.size() == 1 || isDefaultNetwork) { - maybeLogBroadcast(nai, true, type, isDefaultNetwork); - sendLegacyNetworkBroadcast(nai, true, type); + maybeLogBroadcast(nai, DetailedState.CONNECTED, type, isDefaultNetwork); + sendLegacyNetworkBroadcast(nai, DetailedState.CONNECTED, type); } } @@ -538,17 +538,19 @@ public class ConnectivityService extends IConnectivityManager.Stub return; } + final DetailedState state = DetailedState.DISCONNECTED; + if (wasFirstNetwork || wasDefault) { - maybeLogBroadcast(nai, false, type, wasDefault); - sendLegacyNetworkBroadcast(nai, false, type); + maybeLogBroadcast(nai, state, type, wasDefault); + sendLegacyNetworkBroadcast(nai, state, type); } if (!list.isEmpty() && wasFirstNetwork) { if (DBG) log("Other network available for type " + type + ", sending connected broadcast"); final NetworkAgentInfo replacement = list.get(0); - maybeLogBroadcast(replacement, false, type, isDefaultNetwork(replacement)); - sendLegacyNetworkBroadcast(replacement, false, type); + maybeLogBroadcast(replacement, state, type, isDefaultNetwork(replacement)); + sendLegacyNetworkBroadcast(replacement, state, type); } } @@ -560,6 +562,21 @@ public class ConnectivityService extends IConnectivityManager.Stub } } + // send out another legacy broadcast - currently only used for suspend/unsuspend + // toggle + public void update(NetworkAgentInfo nai) { + final boolean isDefault = isDefaultNetwork(nai); + final DetailedState state = nai.networkInfo.getDetailedState(); + for (int type = 0; type < mTypeLists.length; type++) { + final ArrayList<NetworkAgentInfo> list = mTypeLists[type]; + final boolean isFirst = (list != null && list.size() > 0 && nai == list.get(0)); + if (isFirst || isDefault) { + maybeLogBroadcast(nai, state, type, isDefault); + sendLegacyNetworkBroadcast(nai, state, type); + } + } + } + private String naiToString(NetworkAgentInfo nai) { String name = (nai != null) ? nai.name() : "null"; String state = (nai.networkInfo != null) ? @@ -4502,6 +4519,7 @@ public class ConnectivityService extends IConnectivityManager.Stub private void updateNetworkInfo(NetworkAgentInfo networkAgent, NetworkInfo newInfo) { NetworkInfo.State state = newInfo.getState(); NetworkInfo oldInfo = null; + final int oldScore = networkAgent.getCurrentScore(); synchronized (networkAgent) { oldInfo = networkAgent.networkInfo; networkAgent.networkInfo = newInfo; @@ -4560,8 +4578,7 @@ public class ConnectivityService extends IConnectivityManager.Stub // This has to happen after matching the requests, because callbacks are just requests. notifyNetworkCallbacks(networkAgent, ConnectivityManager.CALLBACK_PRECHECK); - } else if (state == NetworkInfo.State.DISCONNECTED || - state == NetworkInfo.State.SUSPENDED) { + } else if (state == NetworkInfo.State.DISCONNECTED) { networkAgent.asyncChannel.disconnect(); if (networkAgent.isVPN()) { synchronized (mProxyLock) { @@ -4573,6 +4590,17 @@ public class ConnectivityService extends IConnectivityManager.Stub } } } + } else if ((oldInfo != null && oldInfo.getState() == NetworkInfo.State.SUSPENDED) || + state == NetworkInfo.State.SUSPENDED) { + // going into or coming out of SUSPEND: rescore and notify + if (networkAgent.getCurrentScore() != oldScore) { + rematchAllNetworksAndRequests(networkAgent, oldScore, + NascentState.NOT_JUST_VALIDATED); + } + notifyNetworkCallbacks(networkAgent, (state == NetworkInfo.State.SUSPENDED ? + ConnectivityManager.CALLBACK_SUSPENDED : + ConnectivityManager.CALLBACK_RESUMED)); + mLegacyTypeTracker.update(networkAgent); } } @@ -4608,7 +4636,7 @@ public class ConnectivityService extends IConnectivityManager.Stub } } - private void sendLegacyNetworkBroadcast(NetworkAgentInfo nai, boolean connected, int type) { + private void sendLegacyNetworkBroadcast(NetworkAgentInfo nai, DetailedState state, int type) { // The NetworkInfo we actually send out has no bearing on the real // state of affairs. For example, if the default connection is mobile, // and a request for HIPRI has just gone away, we need to pretend that @@ -4617,11 +4645,11 @@ public class ConnectivityService extends IConnectivityManager.Stub // and is still connected. NetworkInfo info = new NetworkInfo(nai.networkInfo); info.setType(type); - if (connected) { - info.setDetailedState(DetailedState.CONNECTED, null, info.getExtraInfo()); + if (state != DetailedState.DISCONNECTED) { + info.setDetailedState(state, null, info.getExtraInfo()); sendConnectedBroadcast(info); } else { - info.setDetailedState(DetailedState.DISCONNECTED, info.getReason(), info.getExtraInfo()); + info.setDetailedState(state, info.getReason(), info.getExtraInfo()); Intent intent = new Intent(ConnectivityManager.CONNECTIVITY_ACTION); intent.putExtra(ConnectivityManager.EXTRA_NETWORK_INFO, info); intent.putExtra(ConnectivityManager.EXTRA_NETWORK_TYPE, info.getType()); diff --git a/services/core/java/com/android/server/MountService.java b/services/core/java/com/android/server/MountService.java index 25bd787..da552dd 100644 --- a/services/core/java/com/android/server/MountService.java +++ b/services/core/java/com/android/server/MountService.java @@ -59,6 +59,7 @@ import android.os.Process; import android.os.RemoteCallbackList; import android.os.RemoteException; import android.os.ServiceManager; +import android.os.SystemClock; import android.os.SystemProperties; import android.os.UserHandle; import android.os.UserManager; @@ -128,6 +129,7 @@ import java.util.Map.Entry; import java.util.Objects; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; import javax.crypto.SecretKey; import javax.crypto.SecretKeyFactory; @@ -692,6 +694,15 @@ class MountService extends IMountService.Stub } private void waitForLatch(CountDownLatch latch, String condition) { + try { + waitForLatch(latch, condition, -1); + } catch (TimeoutException ignored) { + } + } + + private void waitForLatch(CountDownLatch latch, String condition, long timeoutMillis) + throws TimeoutException { + final long startMillis = SystemClock.elapsedRealtime(); while (true) { try { if (latch.await(5000, TimeUnit.MILLISECONDS)) { @@ -703,6 +714,10 @@ class MountService extends IMountService.Stub } catch (InterruptedException e) { Slog.w(TAG, "Interrupt while waiting for " + condition); } + if (timeoutMillis > 0 && SystemClock.elapsedRealtime() > startMillis + timeoutMillis) { + throw new TimeoutException("Thread " + Thread.currentThread().getName() + + " gave up waiting for " + condition + " after " + timeoutMillis + "ms"); + } } } @@ -1645,10 +1660,12 @@ class MountService extends IMountService.Stub final CountDownLatch latch = findOrCreateDiskScanLatch(diskId); try { mConnector.execute("volume", "partition", diskId, "public"); + waitForLatch(latch, "partitionPublic", 3 * DateUtils.MINUTE_IN_MILLIS); } catch (NativeDaemonConnectorException e) { throw e.rethrowAsParcelableException(); + } catch (TimeoutException e) { + throw new IllegalStateException(e); } - waitForLatch(latch, "partitionPublic"); } @Override @@ -1660,10 +1677,12 @@ class MountService extends IMountService.Stub final CountDownLatch latch = findOrCreateDiskScanLatch(diskId); try { mConnector.execute("volume", "partition", diskId, "private"); + waitForLatch(latch, "partitionPrivate", 3 * DateUtils.MINUTE_IN_MILLIS); } catch (NativeDaemonConnectorException e) { throw e.rethrowAsParcelableException(); + } catch (TimeoutException e) { + throw new IllegalStateException(e); } - waitForLatch(latch, "partitionPrivate"); } @Override @@ -1675,10 +1694,12 @@ class MountService extends IMountService.Stub final CountDownLatch latch = findOrCreateDiskScanLatch(diskId); try { mConnector.execute("volume", "partition", diskId, "mixed", ratio); + waitForLatch(latch, "partitionMixed", 3 * DateUtils.MINUTE_IN_MILLIS); } catch (NativeDaemonConnectorException e) { throw e.rethrowAsParcelableException(); + } catch (TimeoutException e) { + throw new IllegalStateException(e); } - waitForLatch(latch, "partitionMixed"); } @Override diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java index d00c654..e5a1d02 100644 --- a/wifi/java/android/net/wifi/WifiManager.java +++ b/wifi/java/android/net/wifi/WifiManager.java @@ -1276,7 +1276,10 @@ public class WifiManager { /** * Return the results of the latest access point scan. - * @return the list of access points found in the most recent scan. + * @return the list of access points found in the most recent scan. An app must hold + * {@link android.Manifest.permission#ACCESS_COARSE_LOCATION ACCESS_COARSE_LOCATION} or + * {@link android.Manifest.permission#ACCESS_COARSE_LOCATION ACCESS_FINE_LOCATION} permission + * in order to get valid results. */ public List<ScanResult> getScanResults() { try { |
