/*
 * 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];

            // we don't say anything about the returned value.
            int id = deviceInfo.getId();

            // 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
}
