/*
 * 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.AppOpsManager;
import android.content.Context;
import android.os.Binder;
import android.os.IBinder;
import android.os.MemoryFile;
import android.os.ParcelFileDescriptor;
import android.os.RemoteException;
import android.util.Log;
import android.view.IGraphicsStats;
import android.view.ThreadedRenderer;

import java.io.FileDescriptor;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;

/**
 * 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. This buffer will be pre-initialized with historical
 * data for that process if it exists (if the userId & packageName match a buffer
 * in the historical log)
 *
 * This service does not itself attempt to understand the data in the buffer,
 * its primary job is merely to manage distributing these buffers. However,
 * it is assumed that this buffer is for ThreadedRenderer and delegates
 * directly to ThreadedRenderer for dumping buffers.
 *
 * MEMORY USAGE:
 *
 * This class consumes UP TO:
 * 1) [active rendering processes] * (ASHMEM_SIZE * 2)
 * 2) ASHMEM_SIZE (for scratch space used during dumping)
 * 3) ASHMEM_SIZE * HISTORY_SIZE
 *
 * Currently ASHMEM_SIZE is 256 bytes and HISTORY_SIZE is 20. Assuming
 * the system then also has 10 active rendering processes in the worst case
 * this would end up using under 14KiB (12KiB for the buffers, plus some overhead
 * for userId, pid, package name, and a couple other objects)
 *
 *  @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 ASHMEM_SIZE = 256;
    private static final int HISTORY_SIZE = 20;

    private final Context mContext;
    private final AppOpsManager mAppOps;
    private final Object mLock = new Object();
    private ArrayList<ActiveBuffer> mActive = new ArrayList<>();
    private HistoricalData[] mHistoricalLog = new HistoricalData[HISTORY_SIZE];
    private int mNextHistoricalSlot = 0;
    private byte[] mTempBuffer = new byte[ASHMEM_SIZE];

    public GraphicsStatsService(Context context) {
        mContext = context;
        mAppOps = context.getSystemService(AppOpsManager.class);
    }

    @Override
    public ParcelFileDescriptor requestBufferForProcess(String packageName, IBinder token)
            throws RemoteException {
        int uid = Binder.getCallingUid();
        int pid = Binder.getCallingPid();
        ParcelFileDescriptor pfd = null;
        long callingIdentity = Binder.clearCallingIdentity();
        try {
            mAppOps.checkPackage(uid, packageName);
            synchronized (mLock) {
                pfd = requestBufferForProcessLocked(token, uid, pid, packageName);
            }
        } finally {
            Binder.restoreCallingIdentity(callingIdentity);
        }
        return pfd;
    }

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

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

    private void processDied(ActiveBuffer buffer) {
        synchronized (mLock) {
            mActive.remove(buffer);
            Log.d("GraphicsStats", "Buffer count: " + mActive.size());
        }
        HistoricalData data = buffer.mPreviousData;
        buffer.mPreviousData = null;
        if (data == null) {
            data = mHistoricalLog[mNextHistoricalSlot];
            if (data == null) {
                data = new HistoricalData();
            }
        }
        data.update(buffer.mPackageName, buffer.mUid, buffer.mProcessBuffer);
        buffer.closeAllBuffers();

        mHistoricalLog[mNextHistoricalSlot] = data;
        mNextHistoricalSlot = (mNextHistoricalSlot + 1) % mHistoricalLog.length;
    }

    private ActiveBuffer fetchActiveBuffersLocked(IBinder token, int uid, int pid,
            String packageName) throws RemoteException {
        int size = mActive.size();
        for (int i = 0; i < size; i++) {
            ActiveBuffer buffers = mActive.get(i);
            if (buffers.mPid == pid
                    && buffers.mUid == uid) {
                return buffers;
            }
        }
        // Didn't find one, need to create it
        try {
            ActiveBuffer buffers = new ActiveBuffer(token, uid, pid, packageName);
            mActive.add(buffers);
            return buffers;
        } catch (IOException ex) {
            throw new RemoteException("Failed to allocate space");
        }
    }

    private HistoricalData removeHistoricalDataLocked(int uid, String packageName) {
        for (int i = 0; i < mHistoricalLog.length; i++) {
            final HistoricalData data = mHistoricalLog[i];
            if (data != null && data.mUid == uid
                    && data.mPackageName.equals(packageName)) {
                if (i == mNextHistoricalSlot) {
                    mHistoricalLog[i] = null;
                } else {
                    mHistoricalLog[i] = mHistoricalLog[mNextHistoricalSlot];
                    mHistoricalLog[mNextHistoricalSlot] = null;
                }
                return data;
            }
        }
        return null;
    }

    @Override
    protected void dump(FileDescriptor fd, PrintWriter fout, String[] args) {
        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DUMP, TAG);
        synchronized (mLock) {
            for (int i = 0; i < mActive.size(); i++) {
                final ActiveBuffer buffer = mActive.get(i);
                fout.print("Package: ");
                fout.print(buffer.mPackageName);
                fout.flush();
                try {
                    buffer.mProcessBuffer.readBytes(mTempBuffer, 0, 0, ASHMEM_SIZE);
                    ThreadedRenderer.dumpProfileData(mTempBuffer, fd);
                } catch (IOException e) {
                    fout.println("Failed to dump");
                }
                fout.println();
            }
            for (HistoricalData buffer : mHistoricalLog) {
                if (buffer == null) continue;
                fout.print("Package: ");
                fout.print(buffer.mPackageName);
                fout.flush();
                ThreadedRenderer.dumpProfileData(buffer.mBuffer, fd);
                fout.println();
            }
        }
    }

    private final class ActiveBuffer implements DeathRecipient {
        final int mUid;
        final int mPid;
        final String mPackageName;
        final IBinder mToken;
        MemoryFile mProcessBuffer;
        HistoricalData mPreviousData;

        ActiveBuffer(IBinder token, int uid, int pid, String packageName)
                throws RemoteException, IOException {
            mUid = uid;
            mPid = pid;
            mPackageName = packageName;
            mToken = token;
            mToken.linkToDeath(this, 0);
            mProcessBuffer = new MemoryFile("GFXStats-" + uid, ASHMEM_SIZE);
            mPreviousData = removeHistoricalDataLocked(mUid, mPackageName);
            if (mPreviousData != null) {
                mProcessBuffer.writeBytes(mPreviousData.mBuffer, 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 static class HistoricalData {
        final byte[] mBuffer = new byte[ASHMEM_SIZE];
        int mUid;
        String mPackageName;

        void update(String packageName, int uid, MemoryFile file) {
            mUid = uid;
            mPackageName = packageName;
            try {
                file.readBytes(mBuffer, 0, 0, ASHMEM_SIZE);
            } catch (IOException e) {}
        }
    }
}
