blob: ea6812d2df85220d50640b4de24c608584bf7f0d [file] [log] [blame]
Erik Gilling51e95df2013-06-26 11:06:51 -07001/*
2 * Copyright (C) 2013 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.server;
18
Erik Gilling51e95df2013-06-26 11:06:51 -070019import android.content.Context;
Erik Gilling51e95df2013-06-26 11:06:51 -070020import android.content.pm.PackageManager;
Erik Gilling51e95df2013-06-26 11:06:51 -070021import android.hardware.IConsumerIrService;
Erik Gilling51e95df2013-06-26 11:06:51 -070022import android.os.PowerManager;
Erik Gilling51e95df2013-06-26 11:06:51 -070023import android.util.Slog;
Erik Gilling51e95df2013-06-26 11:06:51 -070024
Alex Ray0c9d61f2013-10-03 12:17:54 -070025import java.lang.RuntimeException;
Erik Gilling51e95df2013-06-26 11:06:51 -070026
27public class ConsumerIrService extends IConsumerIrService.Stub {
28 private static final String TAG = "ConsumerIrService";
29
30 private static final int MAX_XMIT_TIME = 2000000; /* in microseconds */
31
Ashok Bhat0d552f72014-02-07 12:26:17 +000032 private static native long halOpen();
33 private static native int halTransmit(long halObject, int carrierFrequency, int[] pattern);
34 private static native int[] halGetCarrierFrequencies(long halObject);
Erik Gilling51e95df2013-06-26 11:06:51 -070035
36 private final Context mContext;
37 private final PowerManager.WakeLock mWakeLock;
Ashok Bhat0d552f72014-02-07 12:26:17 +000038 private final long mNativeHal;
Erik Gilling51e95df2013-06-26 11:06:51 -070039 private final Object mHalLock = new Object();
40
41 ConsumerIrService(Context context) {
42 mContext = context;
43 PowerManager pm = (PowerManager)context.getSystemService(
44 Context.POWER_SERVICE);
45 mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG);
46 mWakeLock.setReferenceCounted(true);
47
Ashok Bhat0d552f72014-02-07 12:26:17 +000048 mNativeHal = halOpen();
Alex Ray0c9d61f2013-10-03 12:17:54 -070049 if (mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CONSUMER_IR)) {
Ashok Bhat0d552f72014-02-07 12:26:17 +000050 if (mNativeHal == 0) {
Alex Ray0c9d61f2013-10-03 12:17:54 -070051 throw new RuntimeException("FEATURE_CONSUMER_IR present, but no IR HAL loaded!");
52 }
Ashok Bhat0d552f72014-02-07 12:26:17 +000053 } else if (mNativeHal != 0) {
Alex Ray0c9d61f2013-10-03 12:17:54 -070054 throw new RuntimeException("IR HAL present, but FEATURE_CONSUMER_IR is not set!");
Erik Gilling51e95df2013-06-26 11:06:51 -070055 }
56 }
57
58 @Override
59 public boolean hasIrEmitter() {
Ashok Bhat0d552f72014-02-07 12:26:17 +000060 return mNativeHal != 0;
Erik Gilling51e95df2013-06-26 11:06:51 -070061 }
62
63 private void throwIfNoIrEmitter() {
Ashok Bhat0d552f72014-02-07 12:26:17 +000064 if (mNativeHal == 0) {
Erik Gilling51e95df2013-06-26 11:06:51 -070065 throw new UnsupportedOperationException("IR emitter not available");
66 }
67 }
68
69
70 @Override
71 public void transmit(String packageName, int carrierFrequency, int[] pattern) {
72 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.TRANSMIT_IR)
73 != PackageManager.PERMISSION_GRANTED) {
74 throw new SecurityException("Requires TRANSMIT_IR permission");
75 }
76
77 long totalXmitTime = 0;
78
79 for (int slice : pattern) {
80 if (slice <= 0) {
81 throw new IllegalArgumentException("Non-positive IR slice");
82 }
83 totalXmitTime += slice;
84 }
85
86 if (totalXmitTime > MAX_XMIT_TIME ) {
87 throw new IllegalArgumentException("IR pattern too long");
88 }
89
90 throwIfNoIrEmitter();
91
92 // Right now there is no mechanism to ensure fair queing of IR requests
93 synchronized (mHalLock) {
Ashok Bhat0d552f72014-02-07 12:26:17 +000094 int err = halTransmit(mNativeHal, carrierFrequency, pattern);
Erik Gilling51e95df2013-06-26 11:06:51 -070095
96 if (err < 0) {
97 Slog.e(TAG, "Error transmitting: " + err);
98 }
99 }
100 }
101
102 @Override
103 public int[] getCarrierFrequencies() {
104 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.TRANSMIT_IR)
105 != PackageManager.PERMISSION_GRANTED) {
106 throw new SecurityException("Requires TRANSMIT_IR permission");
107 }
108
109 throwIfNoIrEmitter();
110
111 synchronized(mHalLock) {
Ashok Bhat0d552f72014-02-07 12:26:17 +0000112 return halGetCarrierFrequencies(mNativeHal);
Erik Gilling51e95df2013-06-26 11:06:51 -0700113 }
114 }
115}