blob: 8dc7bd40447cbf1bd948e05774a1f711911f81e9 [file] [log] [blame]
/*
* Copyright (C) 2016 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.android.car.systeminterface;
import static com.android.settingslib.display.BrightnessUtils.GAMMA_SPACE_MAX;
import static com.android.settingslib.display.BrightnessUtils.convertGammaToLinear;
import static com.android.settingslib.display.BrightnessUtils.convertLinearToGamma;
import android.content.ContentResolver;
import android.content.Context;
import android.database.ContentObserver;
import android.hardware.display.DisplayManager;
import android.hardware.display.DisplayManager.DisplayListener;
import android.os.Handler;
import android.os.Looper;
import android.os.PowerManager;
import android.os.SystemClock;
import android.provider.Settings.SettingNotFoundException;
import android.provider.Settings.System;
import android.util.Log;
import android.view.Display;
import com.android.car.CarLog;
import com.android.car.CarPowerManagementService;
/**
* Interface that abstracts display operations
*/
public interface DisplayInterface {
/**
* @param brightness Level from 0 to 100%
*/
void setDisplayBrightness(int brightness);
void setDisplayState(boolean on);
void startDisplayStateMonitoring(CarPowerManagementService service);
void stopDisplayStateMonitoring();
class DefaultImpl implements DisplayInterface {
private final ContentResolver mContentResolver;
private final Context mContext;
private final DisplayManager mDisplayManager;
private final int mMaximumBacklight;
private final int mMinimumBacklight;
private final PowerManager mPowerManager;
private final WakeLockInterface mWakeLockInterface;
private CarPowerManagementService mService;
private boolean mDisplayStateSet;
private ContentObserver mBrightnessObserver =
new ContentObserver(new Handler(Looper.getMainLooper())) {
@Override
public void onChange(boolean selfChange) {
int linear = GAMMA_SPACE_MAX;
try {
linear = System.getInt(mContentResolver, System.SCREEN_BRIGHTNESS);
} catch (SettingNotFoundException e) {
Log.e(CarLog.TAG_POWER, "Could not get SCREEN_BRIGHTNESS: " + e);
}
int gamma = convertLinearToGamma(linear, mMinimumBacklight,
mMaximumBacklight);
int percentBright = (gamma * 100 + ((GAMMA_SPACE_MAX + 1) / 2))
/ GAMMA_SPACE_MAX;
mService.sendDisplayBrightness(percentBright);
}
};
private final DisplayManager.DisplayListener mDisplayListener = new DisplayListener() {
@Override
public void onDisplayAdded(int displayId) {
//ignore
}
@Override
public void onDisplayRemoved(int displayId) {
//ignore
}
@Override
public void onDisplayChanged(int displayId) {
if (displayId == Display.DEFAULT_DISPLAY) {
handleMainDisplayChanged();
}
}
};
DefaultImpl(Context context, WakeLockInterface wakeLockInterface) {
mContext = context;
mContentResolver = mContext.getContentResolver();
mDisplayManager = (DisplayManager) context.getSystemService(Context.DISPLAY_SERVICE);
mPowerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
mMaximumBacklight = mPowerManager.getMaximumScreenBrightnessSetting();
mMinimumBacklight = mPowerManager.getMinimumScreenBrightnessSetting();
mWakeLockInterface = wakeLockInterface;
}
private void handleMainDisplayChanged() {
boolean isOn = isMainDisplayOn();
CarPowerManagementService service;
synchronized (this) {
if (mDisplayStateSet == isOn) { // same as what is set
return;
}
service = mService;
}
service.handleMainDisplayChanged(isOn);
}
private boolean isMainDisplayOn() {
Display disp = mDisplayManager.getDisplay(Display.DEFAULT_DISPLAY);
return disp.getState() == Display.STATE_ON;
}
@Override
public void setDisplayBrightness(int percentBright) {
int gamma = (percentBright * GAMMA_SPACE_MAX + 50) / 100;
int linear = convertGammaToLinear(gamma, mMinimumBacklight, mMaximumBacklight);
System.putInt(mContentResolver, System.SCREEN_BRIGHTNESS, linear);
}
@Override
public void startDisplayStateMonitoring(CarPowerManagementService service) {
synchronized (this) {
mService = service;
mDisplayStateSet = isMainDisplayOn();
}
mContentResolver.registerContentObserver(System.getUriFor(System.SCREEN_BRIGHTNESS),
false, mBrightnessObserver);
mDisplayManager.registerDisplayListener(mDisplayListener, service.getHandler());
}
@Override
public void stopDisplayStateMonitoring() {
mDisplayManager.unregisterDisplayListener(mDisplayListener);
mContentResolver.unregisterContentObserver(mBrightnessObserver);
}
@Override
public void setDisplayState(boolean on) {
synchronized (this) {
mDisplayStateSet = on;
}
if (on) {
mWakeLockInterface.switchToFullWakeLock();
Log.i(CarLog.TAG_POWER, "on display");
mPowerManager.wakeUp(SystemClock.uptimeMillis());
} else {
mWakeLockInterface.switchToPartialWakeLock();
Log.i(CarLog.TAG_POWER, "off display");
mPowerManager.goToSleep(SystemClock.uptimeMillis());
}
}
}
}