summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--cmds/pm/src/com/android/commands/pm/Pm.java2
-rw-r--r--core/java/android/net/ConnectivityManager.java91
-rw-r--r--core/java/android/webkit/WebSettings.java6
-rw-r--r--services/core/java/com/android/server/ConnectivityService.java56
-rw-r--r--services/core/java/com/android/server/MountService.java27
-rw-r--r--wifi/java/android/net/wifi/WifiManager.java5
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 {