/*
 * Copyright (C) 2015 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.app.AlarmManager;
import android.app.AppOpsManager;
import android.content.Context;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.os.Binder;
import android.os.Environment;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.IBinder;
import android.os.MemoryFile;
import android.os.Message;
import android.os.ParcelFileDescriptor;
import android.os.Process;
import android.os.RemoteException;
import android.os.Trace;
import android.os.UserHandle;
import android.util.Log;
import android.view.IGraphicsStats;
import android.view.IGraphicsStatsCallback;

import com.android.internal.util.DumpUtils;

import java.io.File;
import java.io.FileDescriptor;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.HashSet;
import java.util.TimeZone;

/**
 * This service's job is to collect aggregate rendering profile data. It
 * does this by allowing rendering processes to request an ashmem buffer
 * to place their stats into.
 *
 * Buffers are rotated on a daily (in UTC) basis and only the 3 most-recent days
 * are kept.
 *
 * The primary consumer of this is incident reports and automated metric checking. It is not
 * intended for end-developer consumption, for that we have gfxinfo.
 *
 * Buffer rotation process:
 * 1) Alarm fires
 * 2) onRotateGraphicsStatsBuffer() is sent to all active processes
 * 3) Upon receiving the callback, the process will stop using the previous ashmem buffer and
 *    request a new one.
 * 4) When that request is received we now know that the ashmem region is no longer in use so
 *    it gets queued up for saving to disk and a new ashmem region is created and returned
 *    for the process to use.
 *
 *  @hide */
public class GraphicsStatsService extends IGraphicsStats.Stub {
    public static final String GRAPHICS_STATS_SERVICE = "graphicsstats";

    private static final String TAG = "GraphicsStatsService";

    private static final int SAVE_BUFFER = 1;
    private static final int DELETE_OLD = 2;

    // This isn't static because we need this to happen after registerNativeMethods, however
    // the class is loaded (and thus static ctor happens) before that occurs.
    private final int ASHMEM_SIZE = nGetAshmemSize();
    private final byte[] ZERO_DATA = new byte[ASHMEM_SIZE];

    private final Context mContext;
    private final AppOpsManager mAppOps;
    private final AlarmManager mAlarmManager;
    private final Object mLock = new Object();
    private ArrayList<ActiveBuffer> mActive = new ArrayList<>();
    private File mGraphicsStatsDir;
    private final Object mFileAccessLock = new Object();
    private Handler mWriteOutHandler;
    private boolean mRotateIsScheduled = false;

    public GraphicsStatsService(Context context) {
        mContext = context;
        mAppOps = context.getSystemService(AppOpsManager.class);
        mAlarmManager = context.getSystemService(AlarmManager.class);
        File systemDataDir = new File(Environment.getDataDirectory(), "system");
        mGraphicsStatsDir = new File(systemDataDir, "graphicsstats");
        mGraphicsStatsDir.mkdirs();
        if (!mGraphicsStatsDir.exists()) {
            throw new IllegalStateException("Graphics stats directory does not exist: "
                    + mGraphicsStatsDir.getAbsolutePath());
        }
        HandlerThread bgthread = new HandlerThread("GraphicsStats-disk", Process.THREAD_PRIORITY_BACKGROUND);
        bgthread.start();

        mWriteOutHandler = new Handler(bgthread.getLooper(), new Handler.Callback() {
            @Override
            public boolean handleMessage(Message msg) {
                switch (msg.what) {
                    case SAVE_BUFFER:
                        saveBuffer((HistoricalBuffer) msg.obj);
                        break;
                    case DELETE_OLD:
                        deleteOldBuffers();
                        break;
                }
                return true;
            }
        });
    }

    /**
     * Current rotation policy is to rotate at midnight UTC. We don't specify RTC_WAKEUP because
     * rotation can be delayed if there's otherwise no activity. However exact is used because
     * we don't want the system to delay it by TOO much.
     */
    private void scheduleRotateLocked() {
        if (mRotateIsScheduled) {
            return;
        }
        mRotateIsScheduled = true;
        Calendar calendar = normalizeDate(System.currentTimeMillis());
        calendar.add(Calendar.DATE, 1);
        mAlarmManager.setExact(AlarmManager.RTC, calendar.getTimeInMillis(), TAG, this::onAlarm,
                mWriteOutHandler);
    }

    private void onAlarm() {
        // We need to make a copy since some of the callbacks won't be proxy and thus
        // can result in a re-entrant acquisition of mLock that would result in a modification
        // of mActive during iteration.
        ActiveBuffer[] activeCopy;
        synchronized (mLock) {
            mRotateIsScheduled = false;
            scheduleRotateLocked();
            activeCopy = mActive.toArray(new ActiveBuffer[0]);
        }
        for (ActiveBuffer active : activeCopy) {
            try {
                active.mCallback.onRotateGraphicsStatsBuffer();
            } catch (RemoteException e) {
                Log.w(TAG, String.format("Failed to notify '%s' (pid=%d) to rotate buffers",
                        active.mInfo.packageName, active.mPid), e);
            }
        }
        // Give a few seconds for everyone to rotate before doing the cleanup
        mWriteOutHandler.sendEmptyMessageDelayed(DELETE_OLD, 10000);
    }

    @Override
    public ParcelFileDescriptor requestBufferForProcess(String packageName, IGraphicsStatsCallback token)
            throws RemoteException {
        int uid = Binder.getCallingUid();
        int pid = Binder.getCallingPid();
        ParcelFileDescriptor pfd = null;
        long callingIdentity = Binder.clearCallingIdentity();
        try {
            mAppOps.checkPackage(uid, packageName);
            PackageInfo info = mContext.getPackageManager().getPackageInfoAsUser(
                    packageName,
                    0,
                    UserHandle.getUserId(uid));
            synchronized (mLock) {
                pfd = requestBufferForProcessLocked(token, uid, pid, packageName, info.versionCode);
            }
        } catch (PackageManager.NameNotFoundException ex) {
            throw new RemoteException("Unable to find package: '" + packageName + "'");
        } finally {
            Binder.restoreCallingIdentity(callingIdentity);
        }
        return pfd;
    }

    private ParcelFileDescriptor getPfd(MemoryFile file) {
        try {
            if (!file.getFileDescriptor().valid()) {
                throw new IllegalStateException("Invalid file descriptor");
            }
            return new ParcelFileDescriptor(file.getFileDescriptor());
        } catch (IOException ex) {
            throw new IllegalStateException("Failed to get PFD from memory file", ex);
        }
    }

    private ParcelFileDescriptor requestBufferForProcessLocked(IGraphicsStatsCallback token,
            int uid, int pid, String packageName, int versionCode) throws RemoteException {
        ActiveBuffer buffer = fetchActiveBuffersLocked(token, uid, pid, packageName, versionCode);
        scheduleRotateLocked();
        return getPfd(buffer.mProcessBuffer);
    }

    private Calendar normalizeDate(long timestamp) {
        Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
        calendar.setTimeInMillis(timestamp);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        return calendar;
    }

    private File pathForApp(BufferInfo info) {
        String subPath = String.format("%d/%s/%d/total",
                normalizeDate(info.startTime).getTimeInMillis(), info.packageName, info.versionCode);
        return new File(mGraphicsStatsDir, subPath);
    }

    private void saveBuffer(HistoricalBuffer buffer) {
        if (Trace.isTagEnabled(Trace.TRACE_TAG_SYSTEM_SERVER)) {
            Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "saving graphicsstats for " + buffer.mInfo.packageName);
        }
        synchronized (mFileAccessLock) {
            File path = pathForApp(buffer.mInfo);
            File parent = path.getParentFile();
            parent.mkdirs();
            if (!parent.exists()) {
                Log.w(TAG, "Unable to create path: '" + parent.getAbsolutePath() + "'");
                return;
            }
            nSaveBuffer(path.getAbsolutePath(), buffer.mInfo.packageName, buffer.mInfo.versionCode,
                    buffer.mInfo.startTime, buffer.mInfo.endTime, buffer.mData);
        }
        Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
    }

    private void deleteRecursiveLocked(File file) {
        if (file.isDirectory()) {
            for (File child : file.listFiles()) {
                deleteRecursiveLocked(child);
            }
        }
        if (!file.delete()) {
            Log.w(TAG, "Failed to delete '" + file.getAbsolutePath() + "'!");
        }
    }

    private void deleteOldBuffers() {
        Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "deleting old graphicsstats buffers");
        synchronized (mFileAccessLock) {
            File[] files = mGraphicsStatsDir.listFiles();
            if (files == null || files.length <= 3) {
                return;
            }
            long[] sortedDates = new long[files.length];
            for (int i = 0; i < files.length; i++) {
                try {
                    sortedDates[i] = Long.parseLong(files[i].getName());
                } catch (NumberFormatException ex) {
                    // Skip unrecognized folders
                }
            }
            if (sortedDates.length <= 3) {
                return;
            }
            Arrays.sort(sortedDates);
            for (int i = 0; i < sortedDates.length - 3; i++) {
                deleteRecursiveLocked(new File(mGraphicsStatsDir, Long.toString(sortedDates[i])));
            }
        }
        Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
    }

    private void addToSaveQueue(ActiveBuffer buffer) {
        try {
            HistoricalBuffer data = new HistoricalBuffer(buffer);
            Message.obtain(mWriteOutHandler, SAVE_BUFFER, data).sendToTarget();
        } catch (IOException e) {
            Log.w(TAG, "Failed to copy graphicsstats from " + buffer.mInfo.packageName, e);
        }
        buffer.closeAllBuffers();
    }

    private void processDied(ActiveBuffer buffer) {
        synchronized (mLock) {
            mActive.remove(buffer);
        }
        addToSaveQueue(buffer);
    }

    private ActiveBuffer fetchActiveBuffersLocked(IGraphicsStatsCallback token, int uid, int pid,
            String packageName, int versionCode) throws RemoteException {
        int size = mActive.size();
        long today = normalizeDate(System.currentTimeMillis()).getTimeInMillis();
        for (int i = 0; i < size; i++) {
            ActiveBuffer buffer = mActive.get(i);
            if (buffer.mPid == pid
                    && buffer.mUid == uid) {
                // If the buffer is too old we remove it and return a new one
                if (buffer.mInfo.startTime < today) {
                    buffer.binderDied();
                    break;
                } else {
                    return buffer;
                }
            }
        }
        // Didn't find one, need to create it
        try {
            ActiveBuffer buffers = new ActiveBuffer(token, uid, pid, packageName, versionCode);
            mActive.add(buffers);
            return buffers;
        } catch (IOException ex) {
            throw new RemoteException("Failed to allocate space");
        }
    }

    private HashSet<File> dumpActiveLocked(long dump, ArrayList<HistoricalBuffer> buffers) {
        HashSet<File> skipFiles = new HashSet<>(buffers.size());
        for (int i = 0; i < buffers.size(); i++) {
            HistoricalBuffer buffer = buffers.get(i);
            File path = pathForApp(buffer.mInfo);
            skipFiles.add(path);
            nAddToDump(dump, path.getAbsolutePath(), buffer.mInfo.packageName,
                    buffer.mInfo.versionCode,  buffer.mInfo.startTime, buffer.mInfo.endTime,
                    buffer.mData);
        }
        return skipFiles;
    }

    private void dumpHistoricalLocked(long dump, HashSet<File> skipFiles) {
        for (File date : mGraphicsStatsDir.listFiles()) {
            for (File pkg : date.listFiles()) {
                for (File version : pkg.listFiles()) {
                    File data = new File(version, "total");
                    if (skipFiles.contains(data)) {
                        continue;
                    }
                    nAddToDump(dump, data.getAbsolutePath());
                }
            }
        }
    }

    @Override
    protected void dump(FileDescriptor fd, PrintWriter fout, String[] args) {
        if (!DumpUtils.checkDumpAndUsageStatsPermission(mContext, TAG, fout)) return;
        boolean dumpProto = false;
        for (String str : args) {
            if ("--proto".equals(str)) {
                dumpProto = true;
                break;
            }
        }
        ArrayList<HistoricalBuffer> buffers;
        synchronized (mLock) {
            buffers = new ArrayList<>(mActive.size());
            for (int i = 0; i < mActive.size(); i++) {
                try {
                    buffers.add(new HistoricalBuffer(mActive.get(i)));
                } catch (IOException ex) {
                    // Ignore
                }
            }
        }
        long dump = nCreateDump(fd.getInt$(), dumpProto);
        try {
            synchronized (mFileAccessLock) {
                HashSet<File> skipList = dumpActiveLocked(dump, buffers);
                buffers.clear();
                dumpHistoricalLocked(dump, skipList);
            }
        } finally {
            nFinishDump(dump);
        }
    }

    private static native int nGetAshmemSize();
    private static native long nCreateDump(int outFd, boolean isProto);
    private static native void nAddToDump(long dump, String path, String packageName,
            int versionCode, long startTime, long endTime, byte[] data);
    private static native void nAddToDump(long dump, String path);
    private static native void nFinishDump(long dump);
    private static native void nSaveBuffer(String path, String packageName, int versionCode,
            long startTime, long endTime, byte[] data);

    private final class BufferInfo {
        final String packageName;
        final int versionCode;
        long startTime;
        long endTime;

        BufferInfo(String packageName, int versionCode, long startTime) {
            this.packageName = packageName;
            this.versionCode = versionCode;
            this.startTime = startTime;
        }
    }

    private final class ActiveBuffer implements DeathRecipient {
        final BufferInfo mInfo;
        final int mUid;
        final int mPid;
        final IGraphicsStatsCallback mCallback;
        final IBinder mToken;
        MemoryFile mProcessBuffer;

        ActiveBuffer(IGraphicsStatsCallback token, int uid, int pid, String packageName, int versionCode)
                throws RemoteException, IOException {
            mInfo = new BufferInfo(packageName, versionCode, System.currentTimeMillis());
            mUid = uid;
            mPid = pid;
            mCallback = token;
            mToken = mCallback.asBinder();
            mToken.linkToDeath(this, 0);
            mProcessBuffer = new MemoryFile("GFXStats-" + pid, ASHMEM_SIZE);
            mProcessBuffer.writeBytes(ZERO_DATA, 0, 0, ASHMEM_SIZE);
        }

        @Override
        public void binderDied() {
            mToken.unlinkToDeath(this, 0);
            processDied(this);
        }

        void closeAllBuffers() {
            if (mProcessBuffer != null) {
                mProcessBuffer.close();
                mProcessBuffer = null;
            }
        }
    }

    private final class HistoricalBuffer {
        final BufferInfo mInfo;
        final byte[] mData = new byte[ASHMEM_SIZE];
        HistoricalBuffer(ActiveBuffer active) throws IOException {
            mInfo = active.mInfo;
            mInfo.endTime = System.currentTimeMillis();
            active.mProcessBuffer.readBytes(mData, 0, 0, ASHMEM_SIZE);
        }
    }
}
