/*
 * Copyright (C) 2012 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.display;

import android.Manifest;
import android.content.Context;
import android.content.pm.PackageManager;
import android.hardware.display.IDisplayManager;
import android.os.Binder;
import android.os.SystemProperties;
import android.view.Display;
import android.view.DisplayInfo;
import android.view.Surface;

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

/**
 * Manages the properties, media routing and power state of attached displays.
 * <p>
 * The display manager service does not own or directly control the displays.
 * Instead, other components in the system register their display adapters with the
 * display manager service which acts as a central controller.
 * </p>
 */
public final class DisplayManagerService extends IDisplayManager.Stub {
    private static final String TAG = "DisplayManagerService";

    private static final String SYSTEM_HEADLESS = "ro.config.headless";

    private final Object mLock = new Object();

    private final Context mContext;
    private final boolean mHeadless;

    private final ArrayList<DisplayAdapter> mDisplayAdapters = new ArrayList<DisplayAdapter>();
    private final DisplayInfo mDefaultDisplayInfo = new DisplayInfo();

    public DisplayManagerService(Context context) {
        mContext = context;
        mHeadless = SystemProperties.get(SYSTEM_HEADLESS).equals("1");

        registerDefaultDisplayAdapter();
    }

    private void registerDefaultDisplayAdapter() {
        if (mHeadless) {
            registerDisplayAdapter(new HeadlessDisplayAdapter(mContext));
        } else {
            registerDisplayAdapter(new SurfaceFlingerDisplayAdapter(mContext));
        }
    }

    // FIXME: this isn't the right API for the long term
    public void getDefaultExternalDisplayDeviceInfo(DisplayDeviceInfo info) {
        // hardcoded assuming 720p touch screen plugged into HDMI and USB
        // need to redesign this
        info.width = 1280;
        info.height = 720;
    }

    /**
     * Returns true if the device is headless.
     *
     * @return True if the device is headless.
     */
    public boolean isHeadless() {
        return mHeadless;
    }

    /**
     * Save away new DisplayInfo data.
     * @param displayId The local DisplayInfo to store the new data in.
     * @param info The new data to be stored.
     */
    public void setDisplayInfo(int displayId, DisplayInfo info) {
        synchronized (mLock) {
            if (displayId != Display.DEFAULT_DISPLAY) {
                throw new UnsupportedOperationException();
            }
            mDefaultDisplayInfo.copyFrom(info);
        }
    }

    /**
     * Return requested DisplayInfo.
     * @param displayId The data to retrieve.
     * @param outInfo The structure to receive the data.
     */
    @Override // Binder call
    public boolean getDisplayInfo(int displayId, DisplayInfo outInfo) {
        synchronized (mLock) {
            if (displayId != Display.DEFAULT_DISPLAY) {
                return false;
            }
            outInfo.copyFrom(mDefaultDisplayInfo);
            return true;
        }
    }

    private void registerDisplayAdapter(DisplayAdapter adapter) {
        mDisplayAdapters.add(adapter);
        adapter.register(new DisplayAdapter.Listener() {
            @Override
            public void onDisplayDeviceAdded(DisplayDevice device) {
                DisplayDeviceInfo deviceInfo = new DisplayDeviceInfo();
                device.getInfo(deviceInfo);
                copyDisplayInfoFromDeviceInfo(mDefaultDisplayInfo, deviceInfo);
            }

            @Override
            public void onDisplayDeviceRemoved(DisplayDevice device) {
            }
        });
    }

    private void copyDisplayInfoFromDeviceInfo(
            DisplayInfo displayInfo, DisplayDeviceInfo deviceInfo) {
        // Bootstrap the logical display using the physical display.
        displayInfo.appWidth = deviceInfo.width;
        displayInfo.appHeight = deviceInfo.height;
        displayInfo.logicalWidth = deviceInfo.width;
        displayInfo.logicalHeight = deviceInfo.height;
        displayInfo.rotation = Surface.ROTATION_0;
        displayInfo.refreshRate = deviceInfo.refreshRate;
        displayInfo.logicalDensityDpi = deviceInfo.densityDpi;
        displayInfo.physicalXDpi = deviceInfo.xDpi;
        displayInfo.physicalYDpi = deviceInfo.yDpi;
        displayInfo.smallestNominalAppWidth = deviceInfo.width;
        displayInfo.smallestNominalAppHeight = deviceInfo.height;
        displayInfo.largestNominalAppWidth = deviceInfo.width;
        displayInfo.largestNominalAppHeight = deviceInfo.height;
    }

    @Override // Binder call
    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
        if (mContext == null
                || mContext.checkCallingOrSelfPermission(Manifest.permission.DUMP)
                        != PackageManager.PERMISSION_GRANTED) {
            pw.println("Permission Denial: can't dump DisplayManager from from pid="
                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid());
            return;
        }

        pw.println("DISPLAY MANAGER (dumpsys display)\n");

        pw.println("Headless: " + mHeadless);

        synchronized (mLock) {
            for (DisplayAdapter adapter : mDisplayAdapters) {
                pw.println("Adapter: " + adapter.getName());
            }

            pw.println("Default display: " + mDefaultDisplayInfo);
        }
    }
}
