blob: e07156ece1b970d6e0dc3f907ae0d05dc0224c64 [file] [log] [blame]
Santos Cordon3107d292016-09-20 15:50:35 -07001/* * Copyright (C) 2008 The Android Open Source Project
Mike Lockwood3a322132009-11-24 00:30:52 -05002 *
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
Adam Lesinski182f73f2013-12-05 16:48:06 -080016package com.android.server.lights;
17
18import com.android.server.SystemService;
Mike Lockwood3a322132009-11-24 00:30:52 -050019
Ruben Brunk49506e02016-04-18 18:10:47 -070020import android.app.ActivityManager;
Mike Lockwood3a322132009-11-24 00:30:52 -050021import android.content.Context;
22import android.os.Handler;
23import android.os.Message;
Jeff Brown3edf5272014-08-14 19:25:14 -070024import android.os.Trace;
Ruben Brunk49506e02016-04-18 18:10:47 -070025import android.provider.Settings;
Joe Onorato8a9b2202010-02-26 18:56:32 -080026import android.util.Slog;
Mike Lockwood3a322132009-11-24 00:30:52 -050027
Adam Lesinski182f73f2013-12-05 16:48:06 -080028public class LightsService extends SystemService {
29 static final String TAG = "LightsService";
30 static final boolean DEBUG = false;
Mike Lockwood3a322132009-11-24 00:30:52 -050031
Adam Lesinski182f73f2013-12-05 16:48:06 -080032 final LightImpl mLights[] = new LightImpl[LightsManager.LIGHT_ID_COUNT];
Mike Lockwood3a322132009-11-24 00:30:52 -050033
Adam Lesinski182f73f2013-12-05 16:48:06 -080034 private final class LightImpl extends Light {
Mike Lockwood3a322132009-11-24 00:30:52 -050035
Adam Lesinski182f73f2013-12-05 16:48:06 -080036 private LightImpl(int id) {
Mike Lockwood3cb67a32009-11-27 14:25:58 -050037 mId = id;
38 }
39
Adam Lesinski182f73f2013-12-05 16:48:06 -080040 @Override
Mike Lockwood3cb67a32009-11-27 14:25:58 -050041 public void setBrightness(int brightness) {
42 setBrightness(brightness, BRIGHTNESS_MODE_USER);
43 }
44
Adam Lesinski182f73f2013-12-05 16:48:06 -080045 @Override
Mike Lockwood3cb67a32009-11-27 14:25:58 -050046 public void setBrightness(int brightness, int brightnessMode) {
47 synchronized (this) {
Santos Cordon3107d292016-09-20 15:50:35 -070048 // LOW_PERSISTENCE cannot be manually set
49 if (brightnessMode == BRIGHTNESS_MODE_LOW_PERSISTENCE) {
50 Slog.w(TAG, "setBrightness with LOW_PERSISTENCE unexpected #" + mId +
51 ": brightness=0x" + Integer.toHexString(brightness));
52 return;
53 }
54
Mike Lockwood3cb67a32009-11-27 14:25:58 -050055 int color = brightness & 0x000000ff;
56 color = 0xff000000 | (color << 16) | (color << 8) | color;
57 setLightLocked(color, LIGHT_FLASH_NONE, 0, 0, brightnessMode);
58 }
59 }
60
Adam Lesinski182f73f2013-12-05 16:48:06 -080061 @Override
Mike Lockwood3cb67a32009-11-27 14:25:58 -050062 public void setColor(int color) {
63 synchronized (this) {
64 setLightLocked(color, LIGHT_FLASH_NONE, 0, 0, 0);
65 }
66 }
67
Adam Lesinski182f73f2013-12-05 16:48:06 -080068 @Override
Mike Lockwood3cb67a32009-11-27 14:25:58 -050069 public void setFlashing(int color, int mode, int onMS, int offMS) {
70 synchronized (this) {
71 setLightLocked(color, mode, onMS, offMS, BRIGHTNESS_MODE_USER);
72 }
73 }
74
Adam Lesinski182f73f2013-12-05 16:48:06 -080075 @Override
Mike Lockwood3cb67a32009-11-27 14:25:58 -050076 public void pulse() {
Mike Lockwood670f9322010-01-20 12:13:36 -050077 pulse(0x00ffffff, 7);
78 }
79
Adam Lesinski182f73f2013-12-05 16:48:06 -080080 @Override
Mike Lockwood670f9322010-01-20 12:13:36 -050081 public void pulse(int color, int onMS) {
Mike Lockwood3cb67a32009-11-27 14:25:58 -050082 synchronized (this) {
83 if (mColor == 0 && !mFlashing) {
Santos Cordon3107d292016-09-20 15:50:35 -070084 setLightLocked(color, LIGHT_FLASH_HARDWARE, onMS, 1000,
85 BRIGHTNESS_MODE_USER);
Oskar Anderoe8467192013-12-03 17:41:27 +010086 mColor = 0;
Mike Lockwood670f9322010-01-20 12:13:36 -050087 mH.sendMessageDelayed(Message.obtain(mH, 1, this), onMS);
Mike Lockwood3cb67a32009-11-27 14:25:58 -050088 }
89 }
90 }
91
Adam Lesinski182f73f2013-12-05 16:48:06 -080092 @Override
Mike Lockwood3cb67a32009-11-27 14:25:58 -050093 public void turnOff() {
94 synchronized (this) {
95 setLightLocked(0, LIGHT_FLASH_NONE, 0, 0, 0);
96 }
97 }
98
Santos Cordon3107d292016-09-20 15:50:35 -070099 @Override
100 public void setVrMode(boolean enabled) {
101 synchronized (this) {
102 if (mVrModeEnabled != enabled) {
103 mVrModeEnabled = enabled;
Ruben Brunk8ad3f202015-12-28 14:45:11 -0800104
Santos Cordon3107d292016-09-20 15:50:35 -0700105 mUseLowPersistenceForVR =
106 (getVrDisplayMode() == Settings.Secure.VR_DISPLAY_MODE_LOW_PERSISTENCE);
107 if (shouldBeInLowPersistenceMode()) {
108 mLastBrightnessMode = mBrightnessMode;
109 }
110
111 // NOTE: We do not trigger a call to setLightLocked here. We do not know the
112 // current brightness or other values when leaving VR so we avoid any incorrect
113 // jumps. The code that calls this method will immediately issue a brightness
114 // update which is when the change will occur.
115 }
Ruben Brunk8ad3f202015-12-28 14:45:11 -0800116 }
117 }
118
Mike Lockwood3cb67a32009-11-27 14:25:58 -0500119 private void stopFlashing() {
120 synchronized (this) {
121 setLightLocked(mColor, LIGHT_FLASH_NONE, 0, 0, BRIGHTNESS_MODE_USER);
122 }
123 }
124
125 private void setLightLocked(int color, int mode, int onMS, int offMS, int brightnessMode) {
Santos Cordon3107d292016-09-20 15:50:35 -0700126 if (shouldBeInLowPersistenceMode()) {
127 brightnessMode = BRIGHTNESS_MODE_LOW_PERSISTENCE;
128 } else if (brightnessMode == BRIGHTNESS_MODE_LOW_PERSISTENCE) {
129 brightnessMode = mLastBrightnessMode;
130 }
131
132 if ((color != mColor || mode != mMode || onMS != mOnMS || offMS != mOffMS ||
Ruben Brunk8ad3f202015-12-28 14:45:11 -0800133 mBrightnessMode != brightnessMode)) {
Dianne Hackbornff801ec2011-01-22 18:05:38 -0800134 if (DEBUG) Slog.v(TAG, "setLight #" + mId + ": color=#"
Ruben Brunk8ad3f202015-12-28 14:45:11 -0800135 + Integer.toHexString(color) + ": brightnessMode=" + brightnessMode);
136 mLastColor = mColor;
Mike Lockwood3cb67a32009-11-27 14:25:58 -0500137 mColor = color;
138 mMode = mode;
139 mOnMS = onMS;
140 mOffMS = offMS;
Ruben Brunk8ad3f202015-12-28 14:45:11 -0800141 mBrightnessMode = brightnessMode;
Jeff Brownfaec22c82015-04-10 12:58:52 -0700142 Trace.traceBegin(Trace.TRACE_TAG_POWER, "setLight(" + mId + ", 0x"
143 + Integer.toHexString(color) + ")");
Jeff Brown3edf5272014-08-14 19:25:14 -0700144 try {
Steven Moreland8b9ec4f2016-10-04 17:25:52 -0700145 setLight_native(mId, color, mode, onMS, offMS, brightnessMode);
Jeff Brown3edf5272014-08-14 19:25:14 -0700146 } finally {
147 Trace.traceEnd(Trace.TRACE_TAG_POWER);
148 }
Mike Lockwood3cb67a32009-11-27 14:25:58 -0500149 }
150 }
151
Santos Cordon3107d292016-09-20 15:50:35 -0700152 private boolean shouldBeInLowPersistenceMode() {
153 return mVrModeEnabled && mUseLowPersistenceForVR;
154 }
155
Mike Lockwood3cb67a32009-11-27 14:25:58 -0500156 private int mId;
157 private int mColor;
158 private int mMode;
159 private int mOnMS;
160 private int mOffMS;
161 private boolean mFlashing;
Ruben Brunk8ad3f202015-12-28 14:45:11 -0800162 private int mBrightnessMode;
163 private int mLastBrightnessMode;
164 private int mLastColor;
Santos Cordon3107d292016-09-20 15:50:35 -0700165 private boolean mVrModeEnabled;
166 private boolean mUseLowPersistenceForVR;
Mike Lockwood3cb67a32009-11-27 14:25:58 -0500167 }
Mike Lockwood3a322132009-11-24 00:30:52 -0500168
Jeff Brownb880d882014-02-10 19:47:07 -0800169 public LightsService(Context context) {
170 super(context);
171
Adam Lesinski182f73f2013-12-05 16:48:06 -0800172 for (int i = 0; i < LightsManager.LIGHT_ID_COUNT; i++) {
173 mLights[i] = new LightImpl(i);
Mike Lockwood3cb67a32009-11-27 14:25:58 -0500174 }
Mike Lockwood3a322132009-11-24 00:30:52 -0500175 }
176
Adam Lesinski182f73f2013-12-05 16:48:06 -0800177 @Override
178 public void onStart() {
Adam Lesinski182f73f2013-12-05 16:48:06 -0800179 publishLocalService(LightsManager.class, mService);
180 }
181
Ruben Brunk8ad3f202015-12-28 14:45:11 -0800182 @Override
183 public void onBootPhase(int phase) {
Ruben Brunk8ad3f202015-12-28 14:45:11 -0800184 }
185
Ruben Brunk49506e02016-04-18 18:10:47 -0700186 private int getVrDisplayMode() {
187 int currentUser = ActivityManager.getCurrentUser();
188 return Settings.Secure.getIntForUser(getContext().getContentResolver(),
189 Settings.Secure.VR_DISPLAY_MODE,
190 /*default*/Settings.Secure.VR_DISPLAY_MODE_LOW_PERSISTENCE,
191 currentUser);
192 }
193
Adam Lesinski182f73f2013-12-05 16:48:06 -0800194 private final LightsManager mService = new LightsManager() {
195 @Override
Jeff Brown5d6443b2015-04-10 20:15:01 -0700196 public Light getLight(int id) {
Steven Moreland8b9ec4f2016-10-04 17:25:52 -0700197 if (0 <= id && id < LIGHT_ID_COUNT) {
Adam Lesinski182f73f2013-12-05 16:48:06 -0800198 return mLights[id];
199 } else {
200 return null;
201 }
202 }
203 };
204
Mike Lockwood3a322132009-11-24 00:30:52 -0500205 private Handler mH = new Handler() {
206 @Override
207 public void handleMessage(Message msg) {
Adam Lesinski182f73f2013-12-05 16:48:06 -0800208 LightImpl light = (LightImpl)msg.obj;
Mike Lockwood3cb67a32009-11-27 14:25:58 -0500209 light.stopFlashing();
Mike Lockwood3a322132009-11-24 00:30:52 -0500210 }
211 };
212
Steven Moreland8b9ec4f2016-10-04 17:25:52 -0700213 static native void setLight_native(int light, int color, int mode,
Mike Lockwood3a322132009-11-24 00:30:52 -0500214 int onMS, int offMS, int brightnessMode);
Mike Lockwood3a322132009-11-24 00:30:52 -0500215}