Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 94f14aec authored by Brad Fitzpatrick's avatar Brad Fitzpatrick Committed by Android (Google) Code Review
Browse files

Merge "More StrictMode work, handling violations in ActivityManagerService." into gingerbread

parents 3a010fa6 46d42387
Loading
Loading
Loading
Loading
+4 −1
Original line number Diff line number Diff line
@@ -1065,8 +1065,9 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM
        case HANDLE_APPLICATION_STRICT_MODE_VIOLATION_TRANSACTION: {
            data.enforceInterface(IActivityManager.descriptor);
            IBinder app = data.readStrongBinder();
            int violationMask = data.readInt();
            ApplicationErrorReport.CrashInfo ci = new ApplicationErrorReport.CrashInfo(data);
            handleApplicationStrictModeViolation(app, ci);
            handleApplicationStrictModeViolation(app, violationMask, ci);
            reply.writeNoException();
            return true;
        }
@@ -2551,12 +2552,14 @@ class ActivityManagerProxy implements IActivityManager
    }

    public void handleApplicationStrictModeViolation(IBinder app,
            int violationMask,
            ApplicationErrorReport.CrashInfo crashInfo) throws RemoteException
    {
        Parcel data = Parcel.obtain();
        Parcel reply = Parcel.obtain();
        data.writeInterfaceToken(IActivityManager.descriptor);
        data.writeStrongBinder(app);
        data.writeInt(violationMask);
        crashInfo.writeToParcel(data, 0);
        mRemote.transact(HANDLE_APPLICATION_STRICT_MODE_VIOLATION_TRANSACTION, data, reply, 0);
        reply.readException();
+0 −1
Original line number Diff line number Diff line
@@ -4139,7 +4139,6 @@ public final class ActivityThread {
         */
        if ((data.appInfo.flags&ApplicationInfo.FLAG_SYSTEM) != 0 &&
            !"user".equals(Build.TYPE)) {
            StrictMode.setDropBoxManager(ContextImpl.createDropBoxManager());
            StrictMode.setThreadBlockingPolicy(
                StrictMode.DISALLOW_DISK_WRITE |
                StrictMode.DISALLOW_DISK_READ |
+5 −1
Original line number Diff line number Diff line
@@ -52,7 +52,6 @@ public class ApplicationErrorReport implements Parcelable {
    // System property defining default error report receiver
    static final String DEFAULT_ERROR_RECEIVER_PROPERTY = "ro.error.receiver.default";

    
    /**
     * Uninitialized error report.
     */
@@ -73,6 +72,11 @@ public class ApplicationErrorReport implements Parcelable {
     */
    public static final int TYPE_BATTERY = 3;

    /**
     * An error report about a StrictMode violation.
     */
    public static final int TYPE_STRICT_MODE_VIOLATION = 4;

    /**
     * Type of this report. Can be one of {@link #TYPE_NONE},
     * {@link #TYPE_CRASH}, {@link #TYPE_ANR}, or {@link #TYPE_BATTERY}.
+6 −1
Original line number Diff line number Diff line
@@ -256,7 +256,12 @@ public interface IActivityManager extends IInterface {
            ApplicationErrorReport.CrashInfo crashInfo) throws RemoteException;
    public boolean handleApplicationWtf(IBinder app, String tag,
            ApplicationErrorReport.CrashInfo crashInfo) throws RemoteException;
    public void handleApplicationStrictModeViolation(IBinder app,

    // A StrictMode violation to be handled.  The violationMask is a
    // subset of the original StrictMode policy bitmask, with only the
    // bit violated and penalty bits to be executed by the
    // ActivityManagerService remaining set.
    public void handleApplicationStrictModeViolation(IBinder app, int violationMask,
            ApplicationErrorReport.CrashInfo crashInfo) throws RemoteException;

    /*
+53 −26
Original line number Diff line number Diff line
@@ -23,6 +23,8 @@ import com.android.internal.os.RuntimeInit;

import dalvik.system.BlockGuard;

import java.util.HashMap;

/**
 * <p>StrictMode lets you impose stricter rules under which your
 * application runs.</p>
@@ -30,6 +32,12 @@ import dalvik.system.BlockGuard;
public final class StrictMode {
    private static final String TAG = "StrictMode";

    // Only log a duplicate stack trace to the logs every second.
    private static final long MIN_LOG_INTERVAL_MS = 1000;

    // Only show an annoying dialog at most every 30 seconds
    private static final long MIN_DIALOG_INTERVAL_MS = 30000;

    private StrictMode() {}

    public static final int DISALLOW_DISK_WRITE = 0x01;
@@ -73,6 +81,10 @@ public final class StrictMode {
     * @param policyMask a bitmask of DISALLOW_* and PENALTY_* values.
     */
    public static void setThreadBlockingPolicy(final int policyMask) {
        if (policyMask == 0) {
            BlockGuard.setThreadPolicy(BlockGuard.LAX_POLICY);
            return;
        }
        BlockGuard.Policy policy = BlockGuard.getThreadPolicy();
        if (!(policy instanceof AndroidBlockGuardPolicy)) {
            BlockGuard.setThreadPolicy(new AndroidBlockGuardPolicy(policyMask));
@@ -91,19 +103,13 @@ public final class StrictMode {
        return BlockGuard.getThreadPolicy().getPolicyMask();
    }

    /** @hide */
    public static void setDropBoxManager(DropBoxManager dropBoxManager) {
        BlockGuard.Policy policy = BlockGuard.getThreadPolicy();
        if (!(policy instanceof AndroidBlockGuardPolicy)) {
            policy = new AndroidBlockGuardPolicy(0);
            BlockGuard.setThreadPolicy(policy);
        }
        ((AndroidBlockGuardPolicy) policy).setDropBoxManager(dropBoxManager);
    }

    private static class AndroidBlockGuardPolicy implements BlockGuard.Policy {
        private int mPolicyMask;
        private DropBoxManager mDropBoxManager = null;

        // Map from violation stacktrace hashcode -> uptimeMillis of
        // last violation.  No locking needed, as this is only
        // accessed by the same thread.
        private final HashMap<Integer, Long> mLastViolationTime = new HashMap<Integer, Long>();

        public AndroidBlockGuardPolicy(final int policyMask) {
            mPolicyMask = policyMask;
@@ -142,10 +148,6 @@ public final class StrictMode {
            mPolicyMask = policyMask;
        }

        public void setDropBoxManager(DropBoxManager dropBoxManager) {
            mDropBoxManager = dropBoxManager;
        }

        private void handleViolation(int violationBit) {
            final BlockGuard.BlockGuardPolicyException violation =
                    new BlockGuard.BlockGuardPolicyException(mPolicyMask, violationBit);
@@ -182,7 +184,23 @@ public final class StrictMode {
            // the old policy here.
            int policy = violation.getPolicy();

            if ((policy & PENALTY_LOG) != 0) {
            // Not _really_ a Crash, but we use the same data structure...
            ApplicationErrorReport.CrashInfo crashInfo =
                    new ApplicationErrorReport.CrashInfo(violation);

            // Not perfect, but fast and good enough for dup suppression.
            Integer crashFingerprint = crashInfo.stackTrace.hashCode();
            long lastViolationTime = 0;
            if (mLastViolationTime.containsKey(crashFingerprint)) {
                lastViolationTime = mLastViolationTime.get(crashFingerprint);
            }
            long now = SystemClock.uptimeMillis();
            mLastViolationTime.put(crashFingerprint, now);
            long timeSinceLastViolationMillis = lastViolationTime == 0 ?
                    Long.MAX_VALUE : (now - lastViolationTime);

            if ((policy & PENALTY_LOG) != 0 &&
                timeSinceLastViolationMillis > MIN_LOG_INTERVAL_MS) {
                if (durationMillis != -1) {
                    Log.d(TAG, "StrictMode policy violation; ~duration=" + durationMillis + " ms",
                          violation);
@@ -191,22 +209,31 @@ public final class StrictMode {
                }
            }

            if ((policy & PENALTY_DIALOG) != 0) {
                // Currently this is just used for the dialog.
            // The violationMask, passed to ActivityManager, is a
            // subset of the original StrictMode policy bitmask, with
            // only the bit violated and penalty bits to be executed
            // by the ActivityManagerService remaining set.
            int violationMask = 0;

            if ((policy & PENALTY_DIALOG) != 0 &&
                timeSinceLastViolationMillis > MIN_DIALOG_INTERVAL_MS) {
                violationMask |= PENALTY_DIALOG;
            }

            if ((policy & PENALTY_DROPBOX) != 0 && lastViolationTime == 0) {
                violationMask |= PENALTY_DROPBOX;
            }

            if (violationMask != 0) {
                violationMask |= violation.getPolicyViolation();
                try {
                    ActivityManagerNative.getDefault().handleApplicationStrictModeViolation(
                        RuntimeInit.getApplicationObject(),
                        violationMask,
                        new ApplicationErrorReport.CrashInfo(violation));
                } catch (RemoteException e) {
                    Log.e(TAG, "RemoteException trying to open strict mode dialog", e);
                }
                    Log.e(TAG, "RemoteException trying to handle StrictMode violation", e);
                }

            if ((policy & PENALTY_DROPBOX) != 0) {
                // TODO: call into ActivityManagerNative to do the dropboxing.
                // But do the first-layer signature dup-checking first client-side.
                // This conditional should be combined with the above, too, along
                // with PENALTY_DEATH below.
            }

            if ((policy & PENALTY_DEATH) != 0) {
Loading