151e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling/*
251e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling * Copyright (C) 2013 The Android Open Source Project
351e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling *
451e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling * Licensed under the Apache License, Version 2.0 (the "License");
551e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling * you may not use this file except in compliance with the License.
651e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling * You may obtain a copy of the License at
751e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling *
851e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling *      http://www.apache.org/licenses/LICENSE-2.0
951e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling *
1051e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling * Unless required by applicable law or agreed to in writing, software
1151e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling * distributed under the License is distributed on an "AS IS" BASIS,
1251e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1351e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling * See the License for the specific language governing permissions and
1451e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling * limitations under the License.
1551e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling */
1651e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling
1751e95df8f24e9ea30775686b9e324b9a671213dcErik Gillingpackage android.hardware;
1851e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling
1951e95df8f24e9ea30775686b9e324b9a671213dcErik Gillingimport android.content.Context;
2051e95df8f24e9ea30775686b9e324b9a671213dcErik Gillingimport android.os.RemoteException;
2151e95df8f24e9ea30775686b9e324b9a671213dcErik Gillingimport android.os.ServiceManager;
2251e95df8f24e9ea30775686b9e324b9a671213dcErik Gillingimport android.util.Log;
2351e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling
2451e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling/**
2551e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling * Class that operates consumer infrared on the device.
2651e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling *
2751e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling * <p>
2851e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling * To obtain an instance of the system infrared transmitter, call
291e679441af2e93841d5dbcddbb28756898108a9fAlex Ray * {@link android.content.Context#getSystemService(java.lang.String)
301e679441af2e93841d5dbcddbb28756898108a9fAlex Ray * Context.getSystemService()} with
311e679441af2e93841d5dbcddbb28756898108a9fAlex Ray * {@link android.content.Context#CONSUMER_IR_SERVICE} as the argument.
3251e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling * </p>
3351e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling */
3451e95df8f24e9ea30775686b9e324b9a671213dcErik Gillingpublic final class ConsumerIrManager {
3551e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling    private static final String TAG = "ConsumerIr";
3651e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling
3751e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling    private final String mPackageName;
3851e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling    private final IConsumerIrService mService;
3951e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling
4051e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling    /**
4151e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling     * @hide to prevent subclassing from outside of the framework
4251e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling     */
4351e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling    public ConsumerIrManager(Context context) {
4451e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling        mPackageName = context.getPackageName();
4551e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling        mService = IConsumerIrService.Stub.asInterface(
4651e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling                ServiceManager.getService(Context.CONSUMER_IR_SERVICE));
4751e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling    }
4851e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling
4951e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling    /**
5051e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling     * Check whether the device has an infrared emitter.
5151e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling     *
5251e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling     * @return true if the device has an infrared emitter, else false.
5351e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling     */
5451e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling    public boolean hasIrEmitter() {
5551e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling        if (mService == null) {
5651e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling            Log.w(TAG, "no consumer ir service.");
5751e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling            return false;
5851e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling        }
5951e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling
6051e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling        try {
6151e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling            return mService.hasIrEmitter();
6251e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling        } catch (RemoteException e) {
6351e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling        }
6451e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling        return false;
6551e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling    }
6651e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling
6751e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling    /**
68991c1005f3060fbf76f7f718317b367189ec51dbMartin Storsjo     * Transmit an infrared pattern
6951e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling     * <p>
7051e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling     * This method is synchronous; when it returns the pattern has
7151e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling     * been transmitted. Only patterns shorter than 2 seconds will
7251e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling     * be transmitted.
7351e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling     * </p>
7451e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling     *
7551e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling     * @param carrierFrequency The IR carrier frequency in Hertz.
7651e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling     * @param pattern The alternating on/off pattern in microseconds to transmit.
7751e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling     */
7851e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling    public void transmit(int carrierFrequency, int[] pattern) {
7951e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling        if (mService == null) {
8051e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling            Log.w(TAG, "failed to transmit; no consumer ir service.");
8151e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling            return;
8251e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling        }
8351e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling
8451e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling        try {
8551e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling            mService.transmit(mPackageName, carrierFrequency, pattern);
8651e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling        } catch (RemoteException e) {
8751e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling            Log.w(TAG, "failed to transmit.", e);
8851e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling        }
8951e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling    }
9051e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling
9151e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling    /**
9251e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling     * Represents a range of carrier frequencies (inclusive) on which the
9351e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling     * infrared transmitter can transmit
9451e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling     */
9551e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling    public final class CarrierFrequencyRange {
9651e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling        private final int mMinFrequency;
9751e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling        private final int mMaxFrequency;
9851e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling
9951e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling        /**
10051e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling         * Create a segment of a carrier frequency range.
10151e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling         *
10251e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling         * @param min The minimum transmittable frequency in this range segment.
10351e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling         * @param max The maximum transmittable frequency in this range segment.
10451e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling         */
10551e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling        public CarrierFrequencyRange(int min, int max) {
10651e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling            mMinFrequency = min;
10751e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling            mMaxFrequency = max;
10851e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling        }
10951e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling
11051e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling        /**
11151e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling         * Get the minimum (inclusive) frequency in this range segment.
11251e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling         */
11351e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling        public int getMinFrequency() {
11451e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling            return mMinFrequency;
11551e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling        }
11651e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling
11751e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling        /**
11851e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling         * Get the maximum (inclusive) frequency in this range segment.
11951e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling         */
12051e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling        public int getMaxFrequency() {
12151e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling            return mMaxFrequency;
12251e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling        }
12351e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling    };
12451e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling
12551e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling    /**
12651e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling     * Query the infrared transmitter's supported carrier frequencies
12751e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling     *
1281e679441af2e93841d5dbcddbb28756898108a9fAlex Ray     * @return an array of
1291e679441af2e93841d5dbcddbb28756898108a9fAlex Ray     * {@link android.hardware.ConsumerIrManager.CarrierFrequencyRange}
1301e679441af2e93841d5dbcddbb28756898108a9fAlex Ray     * objects representing the ranges that the transmitter can support, or
1311e679441af2e93841d5dbcddbb28756898108a9fAlex Ray     * null if there was an error communicating with the Consumer IR Service.
13251e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling     */
13351e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling    public CarrierFrequencyRange[] getCarrierFrequencies() {
13451e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling        if (mService == null) {
13551e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling            Log.w(TAG, "no consumer ir service.");
13651e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling            return null;
13751e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling        }
13851e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling
13951e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling        try {
14051e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling            int[] freqs = mService.getCarrierFrequencies();
14151e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling            if (freqs.length % 2 != 0) {
14251e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling                Log.w(TAG, "consumer ir service returned an uneven number of frequencies.");
14351e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling                return null;
14451e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling            }
14551e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling            CarrierFrequencyRange[] range = new CarrierFrequencyRange[freqs.length / 2];
14651e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling
14751e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling            for (int i = 0; i < freqs.length; i += 2) {
14851e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling                range[i / 2] = new CarrierFrequencyRange(freqs[i], freqs[i+1]);
14951e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling            }
15051e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling            return range;
15151e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling        } catch (RemoteException e) {
15251e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling        }
15351e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling        return null;
15451e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling    }
15551e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling
15651e95df8f24e9ea30775686b9e324b9a671213dcErik Gilling}
157