/*
 * 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.audio;

import android.content.Context;
import android.hardware.display.DisplayManager;
import android.media.AudioSystem;
import android.os.Handler;
import android.util.Log;
import android.view.Surface;
import android.view.WindowManager;

/**
 * Class to handle device rotation events for AudioService, and forward device rotation
 * to the audio HALs through AudioSystem.
 *
 * The role of this class is to monitor device orientation changes, and upon rotation,
 * verify the UI orientation. In case of a change, send the new orientation, in increments
 * of 90deg, through AudioSystem.
 *
 * Note that even though we're responding to device orientation events, we always
 * query the display rotation so audio stays in sync with video/dialogs. This is
 * done with .getDefaultDisplay().getRotation() from WINDOW_SERVICE.
 */
class RotationHelper {

    private static final String TAG = "AudioService.RotationHelper";

    private static AudioDisplayListener sDisplayListener;

    private static final Object sRotationLock = new Object();
    private static int sDeviceRotation = Surface.ROTATION_0; // R/W synchronized on sRotationLock

    private static Context sContext;
    private static Handler sHandler;

    /**
     * post conditions:
     * - sDisplayListener != null
     * - sContext != null
     */
    static void init(Context context, Handler handler) {
        if (context == null) {
            throw new IllegalArgumentException("Invalid null context");
        }
        sContext = context;
        sHandler = handler;
        sDisplayListener = new AudioDisplayListener();
        enable();
    }

    static void enable() {
        ((DisplayManager) sContext.getSystemService(Context.DISPLAY_SERVICE))
                .registerDisplayListener(sDisplayListener, sHandler);
        updateOrientation();
    }

    static void disable() {
        ((DisplayManager) sContext.getSystemService(Context.DISPLAY_SERVICE))
                .unregisterDisplayListener(sDisplayListener);
    }

    /**
     * Query current display rotation and publish the change if any.
     */
    static void updateOrientation() {
        // Even though we're responding to device orientation events,
        // use display rotation so audio stays in sync with video/dialogs
        int newRotation = ((WindowManager) sContext.getSystemService(
                Context.WINDOW_SERVICE)).getDefaultDisplay().getRotation();
        synchronized(sRotationLock) {
            if (newRotation != sDeviceRotation) {
                sDeviceRotation = newRotation;
                publishRotation(sDeviceRotation);
            }
        }
    }

    private static void publishRotation(int rotation) {
        Log.v(TAG, "publishing device rotation =" + rotation + " (x90deg)");
        switch (rotation) {
            case Surface.ROTATION_0:
                AudioSystem.setParameters("rotation=0");
                break;
            case Surface.ROTATION_90:
                AudioSystem.setParameters("rotation=90");
                break;
            case Surface.ROTATION_180:
                AudioSystem.setParameters("rotation=180");
                break;
            case Surface.ROTATION_270:
                AudioSystem.setParameters("rotation=270");
                break;
            default:
                Log.e(TAG, "Unknown device rotation");
        }
    }

    /**
     * Uses android.hardware.display.DisplayManager.DisplayListener
     */
    final static class AudioDisplayListener implements DisplayManager.DisplayListener {

        @Override
        public void onDisplayAdded(int displayId) {
        }

        @Override
        public void onDisplayRemoved(int displayId) {
        }

        @Override
        public void onDisplayChanged(int displayId) {
            updateOrientation();
        }
    }
}