Make network usage on the main thread fatal (Honeycomb+)

For apps targetting Honeycomb SDK or above, make network usage on the
main thread (aka event thread, Looper thread, UI thread) be fatal.

If an app is targetting a previous SDK version, they're grandfathered
into the older (lack of) rules.

Bug: 786847
Change-Id: Ia4ae77b8369567ee526c96b930d523bc722b0bc9
This commit is contained in:
Brad Fitzpatrick
2010-10-28 14:50:05 -07:00
parent 19d928e5a5
commit b6e18412af
4 changed files with 114 additions and 2 deletions

View File

@@ -138635,6 +138635,23 @@
>
</field>
</class>
<class name="NetworkOnMainThreadException"
extends="java.lang.RuntimeException"
abstract="false"
static="false"
final="false"
deprecated="not deprecated"
visibility="public"
>
<constructor name="NetworkOnMainThreadException"
type="android.os.NetworkOnMainThreadException"
static="false"
final="false"
deprecated="not deprecated"
visibility="public"
>
</constructor>
</class>
<class name="Parcel"
extends="java.lang.Object"
abstract="false"
@@ -141746,6 +141763,17 @@
visibility="public"
>
</method>
<method name="penaltyDeathOnNetwork"
return="android.os.StrictMode.ThreadPolicy.Builder"
abstract="false"
native="false"
synchronized="false"
static="false"
final="false"
deprecated="not deprecated"
visibility="public"
>
</method>
<method name="penaltyDialog"
return="android.os.StrictMode.ThreadPolicy.Builder"
abstract="false"
@@ -245077,7 +245105,7 @@
deprecated="not deprecated"
visibility="public"
>
<parameter name="t" type="T">
<parameter name="arg0" type="T">
</parameter>
</method>
</interface>

View File

@@ -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.
*/

View File

@@ -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.
*
* <p>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
* <a href="{@docRoot}guide/practices/design/responsiveness.html">
* Designing for Responsiveness</a>.
*
* <p>Also see {@link StrictMode}.
*/
public class NetworkOnMainThreadException extends RuntimeException {
}

View File

@@ -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.
*
* <p>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
* <em>before</em> anything else. You must still have
* called {@link #detectNetwork} to enable this.
*
* <p>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;
}