diff --git a/api/current.xml b/api/current.xml index 79a56b48fa96f..8d8e96f085fb1 100644 --- a/api/current.xml +++ b/api/current.xml @@ -138635,6 +138635,23 @@ > + + + + + + - + diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java index 754295a9cfa7d..7315f01c8b1e1 100644 --- a/core/java/android/app/ActivityThread.java +++ b/core/java/android/app/ActivityThread.java @@ -3187,6 +3187,17 @@ public final class ActivityThread { StrictMode.conditionallyEnableDebugLogging(); } + /** + * For apps targetting SDK Honeycomb or later, we don't allow + * network usage on the main event loop / UI thread. + * + * Note to those grepping: this is what ultimately throws + * NetworkOnMainThreadException ... + */ + if (data.appInfo.targetSdkVersion > 9) { + StrictMode.enableDeathOnNetwork(); + } + /** * Switch this process to density compatibility mode if needed. */ diff --git a/core/java/android/os/NetworkOnMainThreadException.java b/core/java/android/os/NetworkOnMainThreadException.java new file mode 100644 index 0000000000000..dd8c66cb8bbd0 --- /dev/null +++ b/core/java/android/os/NetworkOnMainThreadException.java @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2010 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.os; + +/** + * The exception that is thrown when an application attempts + * to perform a networking operation on its main thread. + * + *

This is only thrown for applications targeting the Honeycomb + * SDK or higher. Applications targeting earlier SDK versions + * are allowed to do networking on their main event loop threads, + * but it's heavily discouraged. See the document + * + * Designing for Responsiveness. + * + *

Also see {@link StrictMode}. + */ +public class NetworkOnMainThreadException extends RuntimeException { +} diff --git a/core/java/android/os/StrictMode.java b/core/java/android/os/StrictMode.java index 40aceb3713dc1..5a6369c3a5c72 100644 --- a/core/java/android/os/StrictMode.java +++ b/core/java/android/os/StrictMode.java @@ -150,10 +150,19 @@ public final class StrictMode { public static final int PENALTY_DIALOG = 0x20; /** + * Death on any detected violation. + * * @hide */ public static final int PENALTY_DEATH = 0x40; + /** + * Death just for detected network usage. + * + * @hide + */ + public static final int PENALTY_DEATH_ON_NETWORK = 0x200; + /** * @hide */ @@ -176,7 +185,8 @@ public final class StrictMode { * Mask of all the penalty bits. */ private static final int PENALTY_MASK = - PENALTY_LOG | PENALTY_DIALOG | PENALTY_DEATH | PENALTY_DROPBOX | PENALTY_GATHER; + PENALTY_LOG | PENALTY_DIALOG | PENALTY_DEATH | PENALTY_DROPBOX | PENALTY_GATHER | + PENALTY_DEATH_ON_NETWORK; /** * The current VmPolicy in effect. @@ -323,11 +333,27 @@ public final class StrictMode { * Crash the whole process on violation. This penalty runs at * the end of all enabled penalties so you'll still get * see logging or other violations before the process dies. + * + *

Unlike {@link #penaltyDeathOnNetwork}, this applies + * to disk reads, disk writes, and network usage if their + * corresponding detect flags are set. */ public Builder penaltyDeath() { return enable(PENALTY_DEATH); } + /** + * Crash the whole process on any network usage. Unlike + * {@link #penaltyDeath}, this penalty runs + * before anything else. You must still have + * called {@link #detectNetwork} to enable this. + * + *

In the Honeycomb or later SDKs, this is on by default. + */ + public Builder penaltyDeathOnNetwork() { + return enable(PENALTY_DEATH_ON_NETWORK); + } + /** * Log detected violations to the system log. */ @@ -648,6 +674,18 @@ public final class StrictMode { return true; } + /** + * Used by the framework to make network usage on the main + * thread a fatal error. + * + * @hide + */ + public static void enableDeathOnNetwork() { + int oldPolicy = getThreadPolicyMask(); + int newPolicy = oldPolicy | DETECT_NETWORK | PENALTY_DEATH_ON_NETWORK; + setThreadPolicyMask(newPolicy); + } + /** * Parses the BlockGuard policy mask out from the Exception's * getMessage() String value. Kinda gross, but least @@ -758,6 +796,9 @@ public final class StrictMode { if ((mPolicyMask & DETECT_NETWORK) == 0) { return; } + if ((mPolicyMask & PENALTY_DEATH_ON_NETWORK) != 0) { + throw new NetworkOnMainThreadException(); + } if (tooManyViolationsThisLoop()) { return; }