package com.tencent.tws.assistant.services; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.database.ContentObserver; import android.graphics.PixelFormat; import android.net.Uri; import android.os.Handler; import android.os.HandlerThread; import android.os.Looper; import android.os.Message; import android.os.SystemProperties; import android.provider.Settings; import com.tencent.tws.assistant.content.TwsIntent; import com.tencent.tws.assistant.provider.TwsSettings; import android.util.Log; import android.view.Gravity; import android.view.WindowManager; import android.view.WindowManager.LayoutParams; import android.widget.LinearLayout; public class TwsPowerManagerService { Context mtwsContext; private TwsMaskHandler mMaskHandler; private Handler mFaceDetectHandler; static final String TWS_TAG = "TwsPowerManagerService"; static final String TWS_ACTION_START_FACEDETECT = "android.tws.action.start.facedetect"; static final String TWS_ACTION_STOP_FACEDETECT = "android.tws.action.stop.facedetect"; boolean twsmFaceDetectEnabled = true; final static boolean mb_isDebug = false; private boolean mBootComplete = false; private int mBrightnessMode = Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC; void tws_log(String tag, String msg){ if (mb_isDebug){ Log.d(tag, msg); } } public TwsPowerManagerService(Context context) { // TODO Auto-generated constructor stub mtwsContext = context; } public void twsInit(boolean bootComplete){ HandlerThread hthread = new HandlerThread("TwsPowerManagerServiceThread"); hthread.start(); mMaskHandler = new TwsMaskHandler(hthread.getLooper()); isNeedTwsMask(); mFaceDetectHandler = new Handler(); IntentFilter filter = new IntentFilter(); filter.addAction(Intent.ACTION_SCREEN_ON); filter.addAction(Intent.ACTION_SCREEN_OFF); mtwsContext.registerReceiver(mScreenStateChangeReceiver, filter); Uri faceDetecUri = TwsSettings.System.getUriFor(TwsSettings.System.TWS_FACE_DETECT_ENABLE); mtwsContext.getContentResolver().registerContentObserver(faceDetecUri, false, twsmFacedetectObserver); twsmFaceDetectEnabled = TwsSettings.System.getInt(mtwsContext.getContentResolver(), TwsSettings.System.TWS_FACE_DETECT_ENABLE, 0)>0; Uri brightnessModeUri = Settings.System.getUriFor(Settings.System.SCREEN_BRIGHTNESS_MODE); mtwsContext.getContentResolver().registerContentObserver(brightnessModeUri, false, mBrightnessModeObserver); mBrightnessMode = Settings.System.getInt(mtwsContext.getContentResolver(),Settings.System.SCREEN_BRIGHTNESS_MODE, Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC); mCurrentScreenBrightness = Settings.System.getInt(mtwsContext.getContentResolver(), Settings.System.SCREEN_BRIGHTNESS, 100); mBootComplete = bootComplete; if (mBrightnessMode == Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL){ twsSetBacklightBrightness(mCurrentScreenBrightness); } } BroadcastReceiver mScreenStateChangeReceiver = new BroadcastReceiver(){ @Override public void onReceive(Context context, Intent intent) { // TODO Auto-generated method stub if (mBootComplete){ String szAction = intent.getAction(); if (szAction.equals(Intent.ACTION_SCREEN_OFF)){ if (mHaveMasked){ if (mHaveManualChangedWhenAutoMode || mDimMasked){ mMaskHandler.sendEmptyMessage(REMOVE_BRIGHTNESS_MASK); } } mHaveManualChangedWhenAutoMode = false; mDimMasked = false; } } } }; private final int SET_BRIGHTNESS_MASK =2; private final int REMOVE_BRIGHTNESS_MASK =3; class TwsMaskHandler extends Handler{ @Override public void handleMessage(Message msg) { // TODO Auto-generated method stub super.handleMessage(msg); if (msg.what == SET_BRIGHTNESS_MASK){ if (!mHaveMasked){ if (mWindowManager == null){ createFloatView(); } mWindowManager.addView(mFloatLayout, wmParams); mHaveMasked = true; } int value = msg.arg1; setBrightnessMaskValue(value+30); } else if (msg.what == REMOVE_BRIGHTNESS_MASK){ if (mHaveMasked){ setBrightnessMaskValue(100); mWindowManager.removeView(mFloatLayout); mHaveMasked = false; } } } public TwsMaskHandler(Looper looper) { // TODO Auto-generated constructor stub super(looper); } } TwsBrightnessModeObserver mBrightnessModeObserver = new TwsBrightnessModeObserver(new Handler()); class TwsBrightnessModeObserver extends ContentObserver{ public TwsBrightnessModeObserver(Handler handler) { super(handler); // TODO Auto-generated constructor stub } @Override public void onChange(boolean selfChange) { // TODO Auto-generated method stub super.onChange(selfChange); int brightnessMode = Settings.System.getInt(mtwsContext.getContentResolver(),Settings.System.SCREEN_BRIGHTNESS_MODE, Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC); if (brightnessMode != mBrightnessMode){ mBrightnessMode = brightnessMode; if (mBrightnessMode == Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC){ if (mHaveMasked){ mMaskHandler.sendEmptyMessage(REMOVE_BRIGHTNESS_MASK); } } else if (mBrightnessMode == Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL){ int value = Settings.System.getInt(mtwsContext.getContentResolver(),Settings.System.SCREEN_BRIGHTNESS, TwsIntent.TWS_BRIGHTNESS_DIM); twsSetBacklightBrightness(value); } mHaveManualChangedWhenAutoMode = false; } } } TwsFaceDetectObserver twsmFacedetectObserver = new TwsFaceDetectObserver(new Handler()); class TwsFaceDetectObserver extends ContentObserver{ public TwsFaceDetectObserver(Handler handler) { super(handler); // TODO Auto-generated constructor stub } @Override public void onChange(boolean selfChange) { // TODO Auto-generated method stub super.onChange(selfChange); twsmFaceDetectEnabled = TwsSettings.System.getInt(mtwsContext.getContentResolver(), TwsSettings.System.TWS_FACE_DETECT_ENABLE, 0)>0; } } public void twsSetFaceDetectTimeoutLocked(int nextState, int wakelockstate, int dimDelay){ if (mBootComplete && mFaceDetectHandler != null){ mFaceDetectHandler.removeCallbacks(twsmFaceDetectTimeoutTask); // when next state is dim and don't have app acquired screen on bit and user enable the face detect,start the face detect if (twsmFaceDetectEnabled){ if (nextState == TwsIntent.SCREEN_DIM && (wakelockstate & TwsIntent.SCREEN_ON_BIT) == 0){ long nFaceDetectDelay = 0; if (dimDelay > TWS_FACE_DETECT_TIME_GAP){ nFaceDetectDelay = dimDelay - TWS_FACE_DETECT_TIME_GAP; } // Log.d(TWS_TAG, "twsStartFaceDetectTimeoutTask:: nFaceDetectDelay = "+nFaceDetectDelay); mFaceDetectHandler.postDelayed(twsmFaceDetectTimeoutTask, nFaceDetectDelay); } else if (nextState == TwsIntent.SCREEN_BRIGHT){ twsStopFaceDetect(); } } } } static final int TWS_FACE_DETECT_TIME_GAP = 4000; TwsFaceDetectTimeoutTask twsmFaceDetectTimeoutTask = new TwsFaceDetectTimeoutTask(); boolean twsmFaceDetectStarted = false; class TwsFaceDetectTimeoutTask implements Runnable{ @Override public void run() { // TODO Auto-generated method stub twsStartFaceDetect(); } } void twsStopFaceDetect(){ if (twsmFaceDetectStarted){ Intent intent = new Intent(TWS_ACTION_STOP_FACEDETECT); if (intent != null){ // Log.d(TWS_TAG, "twsStopFaceDetect:: stop face detect!"); intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); mtwsContext.sendBroadcast(intent); twsmFaceDetectStarted = false; } } } void twsStartFaceDetect(){ Intent intent = new Intent(TWS_ACTION_START_FACEDETECT); if (intent != null){ // Log.d(TWS_TAG, "twsStartFaceDetect:: start face detect!"); mtwsContext.sendBroadcast(intent); twsmFaceDetectStarted = true; } } private int mPowerState = -1; private boolean mDimMasked = false; public void twsSendPowerStateChangeBroadcast(int newState){ if (mBootComplete && mPowerState!=newState && (mCurrentScreenBrightness >= TwsIntent.TWS_BRIGHTNESS_DIM || (mBrightnessMode == Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC && !mHaveManualChangedWhenAutoMode))){ // Log.d(TWS_TAG, "mPowerState = "+mPowerState +", newState = "+newState); Message msg = Message.obtain(mMaskHandler); if (newState > TwsIntent.SCREEN_DIM && mPowerState == TwsIntent.SCREEN_DIM){ msg.what = REMOVE_BRIGHTNESS_MASK; mDimMasked = false; } else if (newState == TwsIntent.SCREEN_DIM && mPowerState > TwsIntent.SCREEN_DIM){ msg.what = SET_BRIGHTNESS_MASK; msg.arg1 = 20; mDimMasked = true; } mMaskHandler.sendMessage(msg); } mPowerState = newState; } private boolean mIsNeedTwsMask = true; private int mCurrentScreenBrightness; private boolean mHaveMasked = false; private boolean mHaveManualChangedWhenAutoMode = false; private void isNeedTwsMask(){ mIsNeedTwsMask = SystemProperties.getBoolean("ro.tws.brightness_mask", false); } public int twsSetAutoBrightnessValue(int value){ int bRet = value; if(mBootComplete && mHaveManualChangedWhenAutoMode){ bRet = mCurrentScreenBrightness; if (mIsNeedTwsMask){ Message msg = Message.obtain(mMaskHandler); if (bRet < TwsIntent.TWS_BRIGHTNESS_DIM){ msg.what = SET_BRIGHTNESS_MASK; msg.arg1 = bRet; bRet = TwsIntent.TWS_BRIGHTNESS_DIM; } else { msg.what = REMOVE_BRIGHTNESS_MASK; } mMaskHandler.sendMessage(msg); } } return bRet; } public int twsSetBacklightBrightness(int value){ if (!mBootComplete){ return value; } if (mBrightnessMode == Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC){ mHaveManualChangedWhenAutoMode = true; } else { mHaveManualChangedWhenAutoMode = false; } mCurrentScreenBrightness = value; // Log.d(TWS_TAG, "twsSetBacklightBrightness:: value = "+value); if (mIsNeedTwsMask){ Message msg = Message.obtain(mMaskHandler); if (value < TwsIntent.TWS_BRIGHTNESS_DIM){ msg.what = SET_BRIGHTNESS_MASK; msg.arg1 = value; value = TwsIntent.TWS_BRIGHTNESS_DIM; } else { msg.what = REMOVE_BRIGHTNESS_MASK; } mMaskHandler.sendMessage(msg); } return value; } LinearLayout mFloatLayout; WindowManager mWindowManager; WindowManager.LayoutParams wmParams; void createFloatView(){ mWindowManager = (WindowManager) mtwsContext.getSystemService(Context.WINDOW_SERVICE); wmParams = new WindowManager.LayoutParams(); wmParams.flags = LayoutParams.FLAG_NOT_FOCUSABLE // 不需要捕获焦点 | LayoutParams.FLAG_NOT_TOUCHABLE // 不需要响应触摸 | LayoutParams.FLAG_DIM_BEHIND; // 允许调节dimAmount参数 wmParams.type = LayoutParams.TYPE_SYSTEM_OVERLAY; // 盖在所有应用窗口的上面,包括通知栏和锁屏 wmParams.format = PixelFormat.RGBA_8888; wmParams.gravity = Gravity.LEFT | Gravity.TOP; wmParams.dimAmount = 0.0f; wmParams.x = 0; wmParams.y = 0; wmParams.width = 0; wmParams.height = 0; mFloatLayout = new LinearLayout(mtwsContext); mFloatLayout.setBackgroundColor(0x00000000); } void setBrightnessMaskValue(int value){ if (mWindowManager != null && mFloatLayout != null && wmParams != null && mHaveMasked){ float dimValue = 1.0f-(float)value/100.0f; wmParams.dimAmount = dimValue<0.9f?dimValue:0.9f; mWindowManager.updateViewLayout(mFloatLayout, wmParams); } } }