/*
 * Copyright (C) 2018 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;

import android.content.Context;
import android.database.ContentObserver;
import android.net.Uri;
import android.os.Binder;
import android.os.Looper;
import android.os.ResultReceiver;
import android.os.ShellCallback;
import android.os.ShellCommand;
import android.os.SystemProperties;
import android.os.UserHandle;
import android.provider.Settings;
import android.text.format.DateFormat;
import android.util.KeyValueListParser;
import android.util.Slog;

import com.android.internal.os.AppIdToPackageMap;
import com.android.internal.os.BackgroundThread;
import com.android.internal.os.CachedDeviceState;
import com.android.internal.os.LooperStats;
import com.android.internal.util.DumpUtils;

import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;

/**
 * @hide Only for use within the system server.
 */
public class LooperStatsService extends Binder {
    private static final String TAG = "LooperStatsService";
    private static final String LOOPER_STATS_SERVICE_NAME = "looper_stats";
    private static final String SETTINGS_ENABLED_KEY = "enabled";
    private static final String SETTINGS_SAMPLING_INTERVAL_KEY = "sampling_interval";
    private static final String SETTINGS_TRACK_SCREEN_INTERACTIVE_KEY = "track_screen_state";
    private static final String DEBUG_SYS_LOOPER_STATS_ENABLED =
            "debug.sys.looper_stats_enabled";
    private static final int DEFAULT_SAMPLING_INTERVAL = 1000;
    private static final int DEFAULT_ENTRIES_SIZE_CAP = 1500;
    private static final boolean DEFAULT_ENABLED = true;
    private static final boolean DEFAULT_TRACK_SCREEN_INTERACTIVE = false;

    private final Context mContext;
    private final LooperStats mStats;
    // Default should be false so that the first call to #setEnabled installed the looper observer.
    private boolean mEnabled = false;
    private boolean mTrackScreenInteractive = false;

    private LooperStatsService(Context context, LooperStats stats) {
        this.mContext = context;
        this.mStats = stats;
    }

    private void initFromSettings() {
        final KeyValueListParser parser = new KeyValueListParser(',');

        try {
            parser.setString(Settings.Global.getString(mContext.getContentResolver(),
                    Settings.Global.LOOPER_STATS));
        } catch (IllegalArgumentException e) {
            Slog.e(TAG, "Bad looper_stats settings", e);
        }

        setSamplingInterval(
                parser.getInt(SETTINGS_SAMPLING_INTERVAL_KEY, DEFAULT_SAMPLING_INTERVAL));
        setTrackScreenInteractive(
                parser.getBoolean(SETTINGS_TRACK_SCREEN_INTERACTIVE_KEY,
                DEFAULT_TRACK_SCREEN_INTERACTIVE));
        // Manually specified value takes precedence over Settings.
        setEnabled(SystemProperties.getBoolean(
                DEBUG_SYS_LOOPER_STATS_ENABLED,
                parser.getBoolean(SETTINGS_ENABLED_KEY, DEFAULT_ENABLED)));
    }

    @Override
    public void onShellCommand(FileDescriptor in, FileDescriptor out, FileDescriptor err,
            String[] args, ShellCallback callback, ResultReceiver resultReceiver) {
        (new LooperShellCommand()).exec(this, in, out, err, args, callback, resultReceiver);
    }

    @Override
    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
        if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
        AppIdToPackageMap packageMap = AppIdToPackageMap.getSnapshot();
        pw.print("Start time: ");
        pw.println(DateFormat.format("yyyy-MM-dd HH:mm:ss", mStats.getStartTimeMillis()));
        pw.print("On battery time (ms): ");
        pw.println(mStats.getBatteryTimeMillis());
        final List<LooperStats.ExportedEntry> entries = mStats.getEntries();
        entries.sort(Comparator
                .comparing((LooperStats.ExportedEntry entry) -> entry.workSourceUid)
                .thenComparing(entry -> entry.threadName)
                .thenComparing(entry -> entry.handlerClassName)
                .thenComparing(entry -> entry.messageName));
        String header = String.join(",", Arrays.asList(
                "work_source_uid",
                "thread_name",
                "handler_class",
                "message_name",
                "is_interactive",
                "message_count",
                "recorded_message_count",
                "total_latency_micros",
                "max_latency_micros",
                "total_cpu_micros",
                "max_cpu_micros",
                "recorded_delay_message_count",
                "total_delay_millis",
                "max_delay_millis",
                "exception_count"));
        pw.println(header);
        for (LooperStats.ExportedEntry entry : entries) {
            if (entry.messageName.startsWith(LooperStats.DEBUG_ENTRY_PREFIX)) {
                // Do not dump debug entries.
                continue;
            }
            pw.printf("%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s\n",
                    packageMap.mapUid(entry.workSourceUid),
                    entry.threadName,
                    entry.handlerClassName,
                    entry.messageName,
                    entry.isInteractive,
                    entry.messageCount,
                    entry.recordedMessageCount,
                    entry.totalLatencyMicros,
                    entry.maxLatencyMicros,
                    entry.cpuUsageMicros,
                    entry.maxCpuUsageMicros,
                    entry.recordedDelayMessageCount,
                    entry.delayMillis,
                    entry.maxDelayMillis,
                    entry.exceptionCount);
        }
    }

    private void setEnabled(boolean enabled) {
        if (mEnabled != enabled) {
            mEnabled = enabled;
            mStats.reset();
            mStats.setAddDebugEntries(enabled);
            Looper.setObserver(enabled ? mStats : null);
        }
    }

    private void setTrackScreenInteractive(boolean enabled) {
        if (mTrackScreenInteractive != enabled) {
            mTrackScreenInteractive = enabled;
            mStats.reset();
        }
    }

    private void setSamplingInterval(int samplingInterval) {
        if (samplingInterval > 0) {
            mStats.setSamplingInterval(samplingInterval);
        } else {
            Slog.w(TAG, "Ignored invalid sampling interval (value must be positive): "
                    + samplingInterval);
        }
    }

    /**
     * Manages the lifecycle of LooperStatsService within System Server.
     */
    public static class Lifecycle extends SystemService {
        private final SettingsObserver mSettingsObserver;
        private final LooperStatsService mService;
        private final LooperStats mStats;

        public Lifecycle(Context context) {
            super(context);
            mStats = new LooperStats(DEFAULT_SAMPLING_INTERVAL, DEFAULT_ENTRIES_SIZE_CAP);
            mService = new LooperStatsService(getContext(), mStats);
            mSettingsObserver = new SettingsObserver(mService);
        }

        @Override
        public void onStart() {
            publishLocalService(LooperStats.class, mStats);
            publishBinderService(LOOPER_STATS_SERVICE_NAME, mService);
        }

        @Override
        public void onBootPhase(int phase) {
            if (SystemService.PHASE_SYSTEM_SERVICES_READY == phase) {
                mService.initFromSettings();
                Uri settingsUri = Settings.Global.getUriFor(Settings.Global.LOOPER_STATS);
                getContext().getContentResolver().registerContentObserver(
                        settingsUri, false, mSettingsObserver, UserHandle.USER_SYSTEM);
                mStats.setDeviceState(getLocalService(CachedDeviceState.Readonly.class));
            }
        }
    }

    private static class SettingsObserver extends ContentObserver {
        private final LooperStatsService mService;

        SettingsObserver(LooperStatsService service) {
            super(BackgroundThread.getHandler());
            mService = service;
        }

        @Override
        public void onChange(boolean selfChange, Uri uri, int userId) {
            mService.initFromSettings();
        }
    }

    private class LooperShellCommand extends ShellCommand {
        @Override
        public int onCommand(String cmd) {
            if ("enable".equals(cmd)) {
                setEnabled(true);
                return 0;
            } else if ("disable".equals(cmd)) {
                setEnabled(false);
                return 0;
            } else if ("reset".equals(cmd)) {
                mStats.reset();
                return 0;
            } else if ("sampling_interval".equals(cmd)) {
                int sampling = Integer.parseUnsignedInt(getNextArgRequired());
                setSamplingInterval(sampling);
                return 0;
            } else {
                return handleDefaultCommands(cmd);
            }
        }

        @Override
        public void onHelp() {
            final PrintWriter pw = getOutPrintWriter();
            pw.println(LOOPER_STATS_SERVICE_NAME + " commands:");
            pw.println("  enable: Enable collecting stats.");
            pw.println("  disable: Disable collecting stats.");
            pw.println("  sampling_interval: Change the sampling interval.");
            pw.println("  reset: Reset stats.");
        }
    }
}
