/*
 * 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 android.media.cts;

import android.content.Context;
import android.content.pm.PackageManager;

import android.media.AudioDeviceCallback;
import android.media.AudioDeviceInfo;
import android.media.AudioManager;

import android.os.Handler;
import android.os.Looper;

import android.test.AndroidTestCase;

/**
 * TODO: Insert description here. (generated by pmclean)
 */
public class EnumDevicesTest extends AndroidTestCase {
    private AudioManager mAudioManager;

    boolean mAddCallbackCalled = false;
    boolean mRemoveCallbackCalled = false;

    @Override
    protected void setUp() throws Exception {
        super.setUp();

        // get the AudioManager
        mAudioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
        assertNotNull(mAudioManager);
    }

    public void test_getDevices() {
        AudioDeviceInfo[] deviceList;

        // test an empty flags set
        deviceList = mAudioManager.getDevices(0);
        assertTrue(deviceList != null);
        assertTrue(deviceList.length == 0);

        int numOutputDevices = 0;
        if (mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_AUDIO_OUTPUT)) {
            // test OUTPUTS
            deviceList = mAudioManager.getDevices(AudioManager.GET_DEVICES_OUTPUTS);
            assertTrue(deviceList != null);
            numOutputDevices = deviceList.length;
            assertTrue(numOutputDevices != 0);

            // all should be "sinks"
            for(int index = 0; index < numOutputDevices; index++) {
                assertTrue(deviceList[index].isSink());
            }
        }

        int numInputDevices = 0;
        if (mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_MICROPHONE)) {
            // test INPUTS
            deviceList = mAudioManager.getDevices(AudioManager.GET_DEVICES_INPUTS);
            assertTrue(deviceList != null);
            numInputDevices = deviceList.length;
            assertTrue(numInputDevices != 0);

            // all should be "sources"
            for(int index = 0; index < numInputDevices; index++) {
                assertTrue(deviceList[index].isSource());
            }
        }

        // INPUTS & OUTPUTS
        if (mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_AUDIO_OUTPUT) &&
                mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_MICROPHONE)) {
            deviceList = mAudioManager.getDevices(AudioManager.GET_DEVICES_ALL);
            assertTrue(deviceList.length == (numOutputDevices + numInputDevices));
        }
    }

    public void test_devicesInfoFields() {
        AudioDeviceInfo[] deviceList;
        deviceList = mAudioManager.getDevices(AudioManager.GET_DEVICES_ALL);
        for (int index = 0; index < deviceList.length; index++) {
            AudioDeviceInfo deviceInfo = deviceList[index];
            // Product Name
            CharSequence productName = deviceInfo.getProductName();
            assertNotNull(productName);
            assertTrue(productName.length() != 0);

            // Address
            String address = deviceInfo.getAddress();
            assertNotNull(address);
            // address may be empty

            // isSource() XOR isSink()
            assertTrue(deviceInfo.isSource() != deviceInfo.isSink());

            // Sample Rates
            int[] sampleRates = deviceInfo.getSampleRates();
            assertNotNull(sampleRates);
            // "analog" devices won't list any sample rates

            // Channel Masks
            int[] channelMasks = deviceInfo.getChannelMasks();
            assertNotNull(channelMasks);
            // "analog" devices won't list any channel masks

            // Channel Index Masks
            int[] indexMasks = deviceInfo.getChannelIndexMasks();
            assertNotNull(channelMasks);

            // Channel Counts
            int[] channelCounts = deviceInfo.getChannelCounts();
            assertNotNull(channelCounts);
            // "analog" devices won't list any channel Counts

            // Encodings
            int[] encodings = deviceInfo.getEncodings();
            assertNotNull(encodings);
            // "analog" devices won't list any encodings

            int type = deviceInfo.getType();
            assert(type > AudioDeviceInfo.TYPE_UNKNOWN);
        }
    }

    private class EmptyDeviceCallback extends AudioDeviceCallback {
        public void onAudioDevicesAdded(AudioDeviceInfo[] addedDevices) {
            mAddCallbackCalled = true;
        }

        public void onAudioDevicesRemoved(AudioDeviceInfo[] removedDevices) {
            mRemoveCallbackCalled = true;
        }
    }

    /*
     * tests if the Looper for the current thread has been prepared,
     * If not, it makes one, prepares it and returns it.
     * If this returns non-null, the caller is reponsible for calling quit()
     * on the returned Looper.
     */
    private Looper prepareIfNeededLooper() {
        // non-null Handler
        Looper myLooper = null;
        if (Looper.myLooper() == null) {
            Looper.prepare();
            myLooper = Looper.myLooper();
            assertNotNull(myLooper);
        }
        return myLooper;
    }
    
    public void test_deviceCallback() {
        // null callback?
        mAudioManager.registerAudioDeviceCallback(null,null);

        AudioDeviceCallback callback =  new EmptyDeviceCallback();
        AudioDeviceCallback someOtherCallback =  new EmptyDeviceCallback();
        // null Handler
        mAudioManager.registerAudioDeviceCallback(callback, null);

        // unregister null callback
        mAudioManager.unregisterAudioDeviceCallback(null);
        // unregister callback not registered
        mAudioManager.unregisterAudioDeviceCallback(someOtherCallback);
        // nominal case
        mAudioManager.unregisterAudioDeviceCallback(callback);
        // remove twice
        mAudioManager.unregisterAudioDeviceCallback(callback);

        Looper myLooper = prepareIfNeededLooper();
        
        mAudioManager.registerAudioDeviceCallback(callback, new Handler());
        // unregister null callback
        mAudioManager.unregisterAudioDeviceCallback(null);
        // unregister callback not registered
        mAudioManager.unregisterAudioDeviceCallback(someOtherCallback);
        // nominal case
        mAudioManager.unregisterAudioDeviceCallback(callback);
        // remove twice
        mAudioManager.unregisterAudioDeviceCallback(callback);

        if (myLooper != null) {
            myLooper.quit();
        }
    }

    //TODO - Need tests for device connect/disconnect callbacks
}
