/*
 * Copyright (C) 2013 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 com.android.server.am;

import static android.system.OsConstants.AF_UNIX;
import static android.system.OsConstants.SOCK_STREAM;
import static android.system.OsConstants.SOL_SOCKET;
import static android.system.OsConstants.SO_RCVTIMEO;
import static android.system.OsConstants.SO_SNDTIMEO;

import android.app.ApplicationErrorReport.CrashInfo;
import android.system.ErrnoException;
import android.system.Os;
import android.system.StructTimeval;
import android.system.UnixSocketAddress;
import android.util.Slog;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileDescriptor;
import java.io.InterruptedIOException;

/**
 * Set up a Unix domain socket that debuggerd will connect() to in
 * order to write a description of a native crash.  The crash info is
 * then parsed and forwarded to the ActivityManagerService's normal
 * crash handling code.
 *
 * Note that this component runs in a separate thread.
 */
final class NativeCrashListener extends Thread {
    static final String TAG = "NativeCrashListener";
    static final boolean DEBUG = false;
    static final boolean MORE_DEBUG = DEBUG && false;

    // Must match the path defined in debuggerd.c.
    static final String DEBUGGERD_SOCKET_PATH = "/data/system/ndebugsocket";

    // Use a short timeout on socket operations and abandon the connection
    // on hard errors, just in case debuggerd goes out to lunch.
    static final long SOCKET_TIMEOUT_MILLIS = 10000;  // 10 seconds

    final ActivityManagerService mAm;

    /*
     * Spin the actual work of handling a debuggerd crash report into a
     * separate thread so that the listener can go immediately back to
     * accepting incoming connections.
     */
    class NativeCrashReporter extends Thread {
        ProcessRecord mApp;
        int mSignal;
        boolean mGwpAsanRecoverableCrash;
        String mCrashReport;

        NativeCrashReporter(ProcessRecord app, int signal, boolean gwpAsanRecoverableCrash,
                            String report) {
            super("NativeCrashReport");
            mApp = app;
            mSignal = signal;
            mGwpAsanRecoverableCrash = gwpAsanRecoverableCrash;
            mCrashReport = report;
        }

        @Override
        public void run() {
            try {
                CrashInfo ci = new CrashInfo();
                ci.exceptionClassName = "Native crash";
                ci.exceptionMessage = Os.strsignal(mSignal);
                ci.throwFileName = "unknown";
                ci.throwClassName = "unknown";
                ci.throwMethodName = "unknown";
                ci.stackTrace = mCrashReport;

                if (DEBUG) Slog.v(TAG, "Calling handleApplicationCrash()");
                mAm.handleApplicationCrashInner(
                        mGwpAsanRecoverableCrash ? "native_recoverable_crash" : "native_crash",
                        mApp, mApp.processName, ci);
                if (DEBUG) Slog.v(TAG, "<-- handleApplicationCrash() returned");
            } catch (Exception e) {
                Slog.e(TAG, "Unable to report native crash", e);
            }
        }
    }

    /*
     * Daemon thread that accept()s incoming domain socket connections from debuggerd
     * and processes the crash dump that is passed through.
     */
    NativeCrashListener(ActivityManagerService am) {
        mAm = am;
    }

    @Override
    public void run() {
        final byte[] ackSignal = new byte[1];

        if (DEBUG) Slog.i(TAG, "Starting up");

        // The file system entity for this socket is created with 0777 perms, owned
        // by system:system. selinux restricts things so that only crash_dump can
        // access it.
        {
            File socketFile = new File(DEBUGGERD_SOCKET_PATH);
            if (socketFile.exists()) {
                socketFile.delete();
            }
        }

        try {
            FileDescriptor serverFd = Os.socket(AF_UNIX, SOCK_STREAM, 0);
            final UnixSocketAddress sockAddr = UnixSocketAddress.createFileSystem(
                    DEBUGGERD_SOCKET_PATH);
            Os.bind(serverFd, sockAddr);
            Os.listen(serverFd, 1);
            Os.chmod(DEBUGGERD_SOCKET_PATH, 0777);

            while (true) {
                FileDescriptor peerFd = null;
                try {
                    if (MORE_DEBUG) Slog.v(TAG, "Waiting for debuggerd connection");
                    peerFd = Os.accept(serverFd, null /* peerAddress */);
                    if (MORE_DEBUG) Slog.v(TAG, "Got debuggerd socket " + peerFd);
                    if (peerFd != null) {
                        // the reporting thread may take responsibility for
                        // acking the debugger; make sure we play along.
                        consumeNativeCrashData(peerFd);
                    }
                } catch (Exception e) {
                    Slog.w(TAG, "Error handling connection", e);
                } finally {
                    // Always ack crash_dump's connection to us.  The actual
                    // byte written is irrelevant.
                    if (peerFd != null) {
                        try {
                            Os.write(peerFd, ackSignal, 0, 1);
                        } catch (Exception e) {
                            /* we don't care about failures here */
                            if (MORE_DEBUG) {
                                Slog.d(TAG, "Exception writing ack: " + e.getMessage());
                            }
                        }
                        try {
                            Os.close(peerFd);
                        } catch (ErrnoException e) {
                            if (MORE_DEBUG) {
                                Slog.d(TAG, "Exception closing socket: " + e.getMessage());
                            }
                        }
                    }
                }
            }
        } catch (Exception e) {
            Slog.e(TAG, "Unable to init native debug socket!", e);
        }
    }

    static int unpackInt(byte[] buf, int offset) {
        int b0, b1, b2, b3;

        b0 = ((int) buf[offset]) & 0xFF; // mask against sign extension
        b1 = ((int) buf[offset+1]) & 0xFF;
        b2 = ((int) buf[offset+2]) & 0xFF;
        b3 = ((int) buf[offset+3]) & 0xFF;
        return (b0 << 24) | (b1 << 16) | (b2 << 8) | b3;
    }

    static int readExactly(FileDescriptor fd, byte[] buffer, int offset, int numBytes)
            throws ErrnoException, InterruptedIOException {
        int totalRead = 0;
        while (numBytes > 0) {
            int n = Os.read(fd, buffer, offset + totalRead, numBytes);
            if (n <= 0) {
                if (DEBUG) {
                    Slog.w(TAG, "Needed " + numBytes + " but saw " + n);
                }
                return -1;  // premature EOF or timeout
            }
            numBytes -= n;
            totalRead += n;
        }
        return totalRead;
    }

    // Read a crash report from the connection
    void consumeNativeCrashData(FileDescriptor fd) {
        if (MORE_DEBUG) Slog.i(TAG, "debuggerd connected");
        final byte[] buf = new byte[4096];
        final ByteArrayOutputStream os = new ByteArrayOutputStream(4096);

        try {
            StructTimeval timeout = StructTimeval.fromMillis(SOCKET_TIMEOUT_MILLIS);
            Os.setsockoptTimeval(fd, SOL_SOCKET, SO_RCVTIMEO, timeout);
            Os.setsockoptTimeval(fd, SOL_SOCKET, SO_SNDTIMEO, timeout);

            // The socket is guarded by an selinux neverallow rule that only
            // permits crash_dump to connect to it. This allows us to trust the
            // received values.

            // Activity Manager protocol:
            //  - 32-bit network-byte-order: pid
            //  - 32-bit network-byte-order: signal number
            //  - byte: gwpAsanRecoverableCrash
            //  - bytes: raw text of the dump
            //  - null terminator
            int headerBytes = readExactly(fd, buf, 0, 9);
            if (headerBytes != 9) {
                // protocol failure; give up
                Slog.e(TAG, "Unable to read from debuggerd");
                return;
            }

            int pid = unpackInt(buf, 0);
            int signal = unpackInt(buf, 4);
            boolean gwpAsanRecoverableCrash = buf[8] != 0;
            if (DEBUG) {
                Slog.v(TAG, "Read pid=" + pid + " signal=" + signal
                        + " recoverable=" + gwpAsanRecoverableCrash);
            }
            if (pid < 0) {
                Slog.e(TAG, "Bogus pid!");
                return;
            }

            // now the text of the dump
            final ProcessRecord pr;
            synchronized (mAm.mPidsSelfLocked) {
                pr = mAm.mPidsSelfLocked.get(pid);
            }
            if (pr == null) {
                Slog.w(TAG, "Couldn't find ProcessRecord for pid " + pid);
                return;
            }

            // Don't attempt crash reporting for persistent apps
            if (pr.isPersistent()) {
                if (DEBUG) {
                    Slog.v(TAG, "Skipping report for persistent app " + pr);
                }
                return;
            }

            int bytes;
            do {
                // get some data
                bytes = Os.read(fd, buf, 0, buf.length);
                if (bytes > 0) {
                    if (MORE_DEBUG) {
                        String s = new String(buf, 0, bytes, "UTF-8");
                        Slog.v(TAG, "READ=" + bytes + "> " + s);
                    }
                    // did we just get the EOD null byte?
                    if (buf[bytes - 1] == 0) {
                        os.write(buf, 0, bytes - 1); // exclude the EOD token
                        break;
                    }
                    // no EOD, so collect it and read more
                    os.write(buf, 0, bytes);
                }
            } while (bytes > 0);

            // Okay, we've got the report.
            if (DEBUG) Slog.v(TAG, "processing");

            // Mark the process record as being a native crash so that the
            // cleanup mechanism knows we're still submitting the report even
            // though the process will vanish as soon as we let debuggerd
            // proceed. This isn't relevant for recoverable crashes, as we don't
            // show the user an "app crashed" dialogue because the app (by
            // design) didn't crash.
            if (!gwpAsanRecoverableCrash) {
                synchronized (mAm) {
                    synchronized (mAm.mProcLock) {
                        pr.mErrorState.setCrashing(true);
                        pr.mErrorState.setForceCrashReport(true);
                    }
                }
            }

            // Crash reporting is synchronous but we want to let debuggerd
            // go about it business right away, so we spin off the actual
            // reporting logic on a thread and let it take it's time.
            final String reportString = new String(os.toByteArray(), "UTF-8");
            (new NativeCrashReporter(pr, signal, gwpAsanRecoverableCrash, reportString)).start();
        } catch (Exception e) {
            Slog.e(TAG, "Exception dealing with report", e);
            // ugh, fail.
        }
    }

}
