com.google.android.car.kitchensink.volume.VolumeTestFragment.java Source code

Java tutorial

Introduction

Here is the source code for com.google.android.car.kitchensink.volume.VolumeTestFragment.java

Source

/*
 * 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.google.android.car.kitchensink.volume;

import android.car.Car;
import android.car.CarNotConnectedException;
import android.car.media.CarAudioManager;
import android.content.Context;
import android.media.AudioManager;
import android.media.IVolumeController;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.os.RemoteException;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.util.Log;
import android.util.SparseIntArray;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.ListView;

import com.google.android.car.kitchensink.CarEmulator;
import com.google.android.car.kitchensink.R;

public class VolumeTestFragment extends Fragment {
    private static final String TAG = "CarVolumeTest";
    private static final int MSG_VOLUME_CHANGED = 0;
    private static final int MSG_REQUEST_FOCUS = 1;
    private static final int MSG_FOCUS_CHANGED = 2;

    private ListView mVolumeList;
    private Button mRefreshButton;
    private AudioManager mAudioManager;
    private VolumeAdapter mAdapter;

    private CarAudioManager mCarAudioManager;
    private Car mCar;
    private CarEmulator mCarEmulator;

    private Button mVolumeUp;
    private Button mVolumeDown;

    private final VolumeController mVolumeController = new VolumeController();
    private final Handler mHandler = new VolumeHandler();

    private class VolumeHandler extends Handler {
        private AudioFocusListener mFocusListener;

        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
            case MSG_VOLUME_CHANGED:
                initVolumeInfo();
                break;
            case MSG_REQUEST_FOCUS:
                int stream = msg.arg1;
                if (mFocusListener != null) {
                    mAudioManager.abandonAudioFocus(mFocusListener);
                    mVolumeInfos[mStreamIndexMap.get(stream)].mHasFocus = false;
                    mAdapter.notifyDataSetChanged();
                }

                mFocusListener = new AudioFocusListener(stream);
                mAudioManager.requestAudioFocus(mFocusListener, stream, AudioManager.AUDIOFOCUS_GAIN);
                break;
            case MSG_FOCUS_CHANGED:
                int focusStream = msg.arg1;
                mVolumeInfos[mStreamIndexMap.get(focusStream)].mHasFocus = true;
                mAdapter.refreshVolumes(mVolumeInfos);
                break;

            }
        }
    }

    private VolumeInfo[] mVolumeInfos = new VolumeInfo[LOGICAL_STREAMS.length + 1];
    private SparseIntArray mStreamIndexMap = new SparseIntArray(LOGICAL_STREAMS.length);

    private class AudioFocusListener implements AudioManager.OnAudioFocusChangeListener {
        private final int mStream;

        public AudioFocusListener(int stream) {
            mStream = stream;
        }

        @Override
        public void onAudioFocusChange(int focusChange) {
            if (focusChange == AudioManager.AUDIOFOCUS_GAIN) {
                mHandler.sendMessage(mHandler.obtainMessage(MSG_FOCUS_CHANGED, mStream, 0));
            } else {
                Log.e(TAG, "Audio focus request failed");
            }
        }
    }

    public static class VolumeInfo {
        public int logicalStream;
        public String mId;
        public String mMax;
        public String mCurrent;
        public String mLogicalMax;
        public String mLogicalCurrent;
        public boolean mHasFocus;
    }

    private static final int LOGICAL_STREAMS[] = { AudioManager.STREAM_MUSIC, AudioManager.STREAM_ALARM,
            AudioManager.STREAM_NOTIFICATION, AudioManager.STREAM_RING, AudioManager.STREAM_VOICE_CALL,
            AudioManager.STREAM_SYSTEM
            //            AudioManager.STREAM_DTMF,
    };

    private static String streamToName(int stream) {
        switch (stream) {
        case AudioManager.STREAM_ALARM:
            return "Alarm";
        case AudioManager.STREAM_MUSIC:
            return "Music";
        case AudioManager.STREAM_NOTIFICATION:
            return "Notification";
        case AudioManager.STREAM_RING:
            return "Ring";
        case AudioManager.STREAM_VOICE_CALL:
            return "Call";
        case AudioManager.STREAM_SYSTEM:
            return "System";
        default:
            return "Unknown";
        }
    }

    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container,
            @Nullable Bundle savedInstanceState) {
        View v = inflater.inflate(R.layout.volume_test, container, false);

        mVolumeList = (ListView) v.findViewById(R.id.volume_list);
        mAudioManager = (AudioManager) getContext().getSystemService(Context.AUDIO_SERVICE);

        mRefreshButton = (Button) v.findViewById(R.id.refresh);
        mAdapter = new VolumeAdapter(getContext(), R.layout.volume_item, mVolumeInfos, this);
        mVolumeList.setAdapter(mAdapter);

        mRefreshButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                initVolumeInfo();
            }
        });

        mCarEmulator = CarEmulator.create(getContext());
        mCar = mCarEmulator.getCar();
        try {
            mCarAudioManager = (CarAudioManager) mCar.getCarManager(Car.AUDIO_SERVICE);
            initVolumeInfo();
            mCarAudioManager.setVolumeController(mVolumeController);
        } catch (CarNotConnectedException e) {
            throw new RuntimeException(e); // Should never occur in car emulator.
        }

        mVolumeUp = (Button) v.findViewById(R.id.volume_up);
        mVolumeDown = (Button) v.findViewById(R.id.volume_down);

        mVolumeUp.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                mCarEmulator.injectKey(KeyEvent.KEYCODE_VOLUME_UP);
            }
        });

        mVolumeDown.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                mCarEmulator.injectKey(KeyEvent.KEYCODE_VOLUME_DOWN);
            }
        });

        return v;
    }

    public void adjustVolumeByOne(int logicalStream, boolean up) {
        if (mCarAudioManager == null) {
            Log.e(TAG, "CarAudioManager is null");
            return;
        }
        int current = 0;
        try {
            current = mCarAudioManager.getStreamVolume(logicalStream);
        } catch (CarNotConnectedException e) {
            Log.e(TAG, "car not connected", e);
        }
        setStreamVolume(logicalStream, current + (up ? 1 : -1));
    }

    public void requestFocus(int logicalStream) {
        mHandler.sendMessage(mHandler.obtainMessage(MSG_REQUEST_FOCUS, logicalStream));
    }

    public void setStreamVolume(int logicalStream, int volume) {
        if (mCarAudioManager == null) {
            Log.e(TAG, "CarAudioManager is null");
            return;
        }
        try {
            mCarAudioManager.setStreamVolume(logicalStream, volume, 0);
        } catch (CarNotConnectedException e) {
            Log.e(TAG, "car not connected", e);
        }

        Log.d(TAG, "Set stream " + logicalStream + " volume " + volume);
    }

    private void initVolumeInfo() {
        if (mVolumeInfos[0] == null) {
            mVolumeInfos[0] = new VolumeInfo();
            mVolumeInfos[0].mId = "Stream";
            mVolumeInfos[0].mCurrent = "Current";
            mVolumeInfos[0].mMax = "Max";
            mVolumeInfos[0].mLogicalMax = "Android_Max";
            mVolumeInfos[0].mLogicalCurrent = "Android_Current";

        }
        int i = 1;
        for (int stream : LOGICAL_STREAMS) {
            if (mVolumeInfos[i] == null) {
                mVolumeInfos[i] = new VolumeInfo();
            }
            mVolumeInfos[i].logicalStream = stream;
            mStreamIndexMap.put(stream, i);
            mVolumeInfos[i].mId = streamToName(stream);

            int current = 0;
            int max = 0;
            try {
                current = mCarAudioManager.getStreamVolume(stream);
                max = mCarAudioManager.getStreamMaxVolume(stream);
            } catch (CarNotConnectedException e) {
                Log.e(TAG, "car not connected", e);
            }

            mVolumeInfos[i].mCurrent = String.valueOf(current);
            mVolumeInfos[i].mMax = String.valueOf(max);

            mVolumeInfos[i].mLogicalMax = String.valueOf(mAudioManager.getStreamMaxVolume(stream));
            mVolumeInfos[i].mLogicalCurrent = String.valueOf(mAudioManager.getStreamVolume(stream));

            Log.d(TAG, stream + " max: " + mVolumeInfos[i].mMax + " current: " + mVolumeInfos[i].mCurrent);
            i++;
        }
        mAdapter.refreshVolumes(mVolumeInfos);
    }

    @Override
    public void onDestroy() {
        if (mCar != null) {
            mCar.disconnect();
        }
        super.onDestroy();
    }

    private class VolumeController extends IVolumeController.Stub {

        @Override
        public void displaySafeVolumeWarning(int flags) throws RemoteException {
        }

        @Override
        public void volumeChanged(int streamType, int flags) throws RemoteException {
            mHandler.sendMessage(mHandler.obtainMessage(MSG_VOLUME_CHANGED, streamType));
        }

        @Override
        public void masterMuteChanged(int flags) throws RemoteException {
        }

        @Override
        public void setLayoutDirection(int layoutDirection) throws RemoteException {
        }

        @Override
        public void dismiss() throws RemoteException {
        }

        @Override
        public void setA11yMode(int mode) throws RemoteException {
        }
    }
}