blob: 583f1bc762536c8d9279a3b655cb305707db11a5 [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
19import android.content.BroadcastReceiver;
20import android.content.Context;
21import android.content.Intent;
22import android.content.IntentFilter;
23import android.content.pm.PackageManager;
24import android.database.ContentObserver;
25import android.hardware.input.InputManager;
26import android.hardware.IConsumerIrService;
27import android.os.Handler;
28import android.os.PowerManager;
29import android.os.Process;
30import android.os.RemoteException;
31import android.os.IBinder;
32import android.os.Binder;
33import android.os.ServiceManager;
34import android.os.SystemClock;
35import android.os.UserHandle;
36import android.os.WorkSource;
37import android.provider.Settings;
38import android.provider.Settings.SettingNotFoundException;
39import android.util.Slog;
40import android.view.InputDevice;
41
Alex Ray0c9d61f2013-10-03 12:17:54 -070042import java.lang.RuntimeException;
Erik Gilling51e95df2013-06-26 11:06:51 -070043import java.util.ArrayList;
44import java.util.LinkedList;
45import java.util.ListIterator;
46
47public class ConsumerIrService extends IConsumerIrService.Stub {
48 private static final String TAG = "ConsumerIrService";
49
50 private static final int MAX_XMIT_TIME = 2000000; /* in microseconds */
51
Ashok Bhat0d552f72014-02-07 12:26:17 +000052 private static native long halOpen();
53 private static native int halTransmit(long halObject, int carrierFrequency, int[] pattern);
54 private static native int[] halGetCarrierFrequencies(long halObject);
Erik Gilling51e95df2013-06-26 11:06:51 -070055
56 private final Context mContext;
57 private final PowerManager.WakeLock mWakeLock;
Ashok Bhat0d552f72014-02-07 12:26:17 +000058 private final long mNativeHal;
Erik Gilling51e95df2013-06-26 11:06:51 -070059 private final Object mHalLock = new Object();
60
61 ConsumerIrService(Context context) {
62 mContext = context;
63 PowerManager pm = (PowerManager)context.getSystemService(
64 Context.POWER_SERVICE);
65 mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG);
66 mWakeLock.setReferenceCounted(true);
67
Ashok Bhat0d552f72014-02-07 12:26:17 +000068 mNativeHal = halOpen();
Alex Ray0c9d61f2013-10-03 12:17:54 -070069 if (mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CONSUMER_IR)) {
Ashok Bhat0d552f72014-02-07 12:26:17 +000070 if (mNativeHal == 0) {
Alex Ray0c9d61f2013-10-03 12:17:54 -070071 throw new RuntimeException("FEATURE_CONSUMER_IR present, but no IR HAL loaded!");
72 }
Ashok Bhat0d552f72014-02-07 12:26:17 +000073 } else if (mNativeHal != 0) {
Alex Ray0c9d61f2013-10-03 12:17:54 -070074 throw new RuntimeException("IR HAL present, but FEATURE_CONSUMER_IR is not set!");
Erik Gilling51e95df2013-06-26 11:06:51 -070075 }
76 }
77
78 @Override
79 public boolean hasIrEmitter() {
Ashok Bhat0d552f72014-02-07 12:26:17 +000080 return mNativeHal != 0;
Erik Gilling51e95df2013-06-26 11:06:51 -070081 }
82
83 private void throwIfNoIrEmitter() {
Ashok Bhat0d552f72014-02-07 12:26:17 +000084 if (mNativeHal == 0) {
Erik Gilling51e95df2013-06-26 11:06:51 -070085 throw new UnsupportedOperationException("IR emitter not available");
86 }
87 }
88
89
90 @Override
91 public void transmit(String packageName, int carrierFrequency, int[] pattern) {
92 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.TRANSMIT_IR)
93 != PackageManager.PERMISSION_GRANTED) {
94 throw new SecurityException("Requires TRANSMIT_IR permission");
95 }
96
97 long totalXmitTime = 0;
98
99 for (int slice : pattern) {
100 if (slice <= 0) {
101 throw new IllegalArgumentException("Non-positive IR slice");
102 }
103 totalXmitTime += slice;
104 }
105
106 if (totalXmitTime > MAX_XMIT_TIME ) {
107 throw new IllegalArgumentException("IR pattern too long");
108 }
109
110 throwIfNoIrEmitter();
111
112 // Right now there is no mechanism to ensure fair queing of IR requests
113 synchronized (mHalLock) {
Ashok Bhat0d552f72014-02-07 12:26:17 +0000114 int err = halTransmit(mNativeHal, carrierFrequency, pattern);
Erik Gilling51e95df2013-06-26 11:06:51 -0700115
116 if (err < 0) {
117 Slog.e(TAG, "Error transmitting: " + err);
118 }
119 }
120 }
121
122 @Override
123 public int[] getCarrierFrequencies() {
124 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.TRANSMIT_IR)
125 != PackageManager.PERMISSION_GRANTED) {
126 throw new SecurityException("Requires TRANSMIT_IR permission");
127 }
128
129 throwIfNoIrEmitter();
130
131 synchronized(mHalLock) {
Ashok Bhat0d552f72014-02-07 12:26:17 +0000132 return halGetCarrierFrequencies(mNativeHal);
Erik Gilling51e95df2013-06-26 11:06:51 -0700133 }
134 }
135}