Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e22626c1 authored by Park Ju Hyung's avatar Park Ju Hyung Committed by Joey Rizzoli
Browse files

[1/3] SystemUI: add burnIn protection setting



Devices with OLED display suffer from
status-bar's notification items and nagivation bar's software keys
causing permanent burn-ins when used long-term.

Moving all items in the area
both horizontally and vertically workarounds this problem.

jrizzoli: integrate with runtime cmsdk preference

Change-Id: I35b04d1edff86a556adb3ad349569e5d82653f16
Signed-off-by: default avatarPark Ju Hyung <qkrwngud825@gmail.com>
Signed-off-by: default avatarAlex Naidis <alex.naidis@linux.com>
Signed-off-by: default avatarThecrazyskull <anaskarbila@gmail.com>
Signed-off-by: default avatarJoey Rizzoli <joey@lineageos.org>
parent 1e27dad1
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -29,4 +29,7 @@

    <dimen name="navbar_single_hand_mode_horizontal_threshhold">90dp</dimen>
    <dimen name="navbar_single_hand_mode_vertical_threshhold">48dp</dimen>

    <dimen name="burnin_protection_horizontal_shift">3dp</dimen>
    <dimen name="burnin_protection_vertical_shift">1dp</dimen>
</resources>
+26 −0
Original line number Diff line number Diff line
@@ -115,6 +115,13 @@ public class NavigationBarView extends LinearLayout implements TunerService.Tuna

    private NavigationBarInflaterView mNavigationInflaterView;

    private int mBasePaddingBottom;
    private int mBasePaddingLeft;
    private int mBasePaddingRight;
    private int mBasePaddingTop;

    private ViewGroup mNavigationBarContents;

    private class NavTransitionListener implements TransitionListener {
        private boolean mBackTransitioning;
        private boolean mHomeAppearing;
@@ -500,6 +507,18 @@ public class NavigationBarView extends LinearLayout implements TunerService.Tuna
        getSearchButton().setVisibility(shouldShowAlwaysMenu ? View.VISIBLE : View.INVISIBLE);
    }

    public void shiftNavigationBarItems(int horizontalShift, int verticalShift) {
        if (mNavigationBarContents == null) {
            return;
        }

        mNavigationBarContents.setPaddingRelative(mBasePaddingLeft + horizontalShift,
                mBasePaddingTop + verticalShift,
                mBasePaddingRight + horizontalShift,
                mBasePaddingBottom - verticalShift);
        invalidate();
    }

    @Override
    public void onFinishInflate() {
        mNavigationInflaterView = (NavigationBarInflaterView) findViewById(
@@ -509,6 +528,13 @@ public class NavigationBarView extends LinearLayout implements TunerService.Tuna

        getImeSwitchButton().setOnClickListener(mImeSwitcherClickListener);

        mNavigationBarContents = (ViewGroup) getCurrentView().findViewById(R.id.nav_buttons);

        mBasePaddingLeft = mNavigationBarContents.getPaddingStart();
        mBasePaddingTop = mNavigationBarContents.getPaddingTop();
        mBasePaddingRight = mNavigationBarContents.getPaddingEnd();
        mBasePaddingBottom = mNavigationBarContents.getPaddingBottom();

        try {
            WindowManagerGlobal.getWindowManagerService().registerDockedStackListener(new Stub() {
                @Override
+31 −0
Original line number Diff line number Diff line
@@ -187,6 +187,7 @@ import com.android.systemui.statusbar.policy.BatteryController.BatteryStateChang
import com.android.systemui.statusbar.policy.BatteryControllerImpl;
import com.android.systemui.statusbar.policy.BluetoothControllerImpl;
import com.android.systemui.statusbar.policy.BrightnessMirrorController;
import com.android.systemui.statusbar.policy.BurnInProtectionController;
import com.android.systemui.statusbar.policy.CastControllerImpl;
import com.android.systemui.statusbar.policy.EncryptionHelper;
import com.android.systemui.statusbar.policy.FlashlightController;
@@ -323,6 +324,8 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
            "cmsystem:" + CMSettings.System.NAVBAR_LEFT_IN_LANDSCAPE;
    private static final String LOCKSCREEN_MEDIA_METADATA =
            "cmsecure:" + CMSettings.Secure.LOCKSCREEN_MEDIA_METADATA;
    private static final String SYSTEMUI_BURNIN_PROTECTION =
            "cmsecure:" + CMSettings.System.SYSTEMUI_BURNIN_PROTECTION;

    static {
        boolean onlyCoreApps;
@@ -367,6 +370,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
    protected LockscreenWallpaper mLockscreenWallpaper;
    SuControllerImpl mSuController;
    WeatherControllerImpl mWeatherController;
    private BurnInProtectionController mBurnInProtectionController;

    int mNaturalBarHeight = -1;

@@ -511,6 +515,10 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
            } else {
                removeNavigationBar();
            }
            if (mBurnInProtectionController != null) {
                mBurnInProtectionController.setNavigationBarView(
                        visible ? mNavigationBarView : null);
            }
        }
    }

@@ -614,6 +622,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
    private boolean mScreenOn;
    private boolean mKeyguardShowingMedia;
    private boolean mShowMediaMetadata;
    private boolean mBurnInProtectionEnabled;

    private MediaSessionManager mMediaSessionManager;
    private MediaController mMediaController;
@@ -920,6 +929,11 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
            mNotificationPanelDebugText.setVisibility(View.VISIBLE);
        }

        if (mContext.getResources().getBoolean(
                org.cyanogenmod.platform.internal.R.bool.config_enableBurnInProtection)) {
            mBurnInProtectionController = new BurnInProtectionController(mContext, mStatusBarView);
        }

        try {
            boolean showNav = mWindowManagerService.hasNavigationBar();
            if (DEBUG) Log.v(TAG, "hasNavigationBar=" + showNav);
@@ -5139,6 +5153,9 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
        mStackScroller.setAnimationsEnabled(false);
        mVisualStabilityManager.setScreenOn(false);
        updateVisibleToUser();
        if (mBurnInProtectionController != null) {
            mBurnInProtectionController.stopShiftTimer(mBurnInProtectionEnabled);
        }
        if (mLaunchCameraOnFinishedGoingToSleep) {
            mLaunchCameraOnFinishedGoingToSleep = false;

@@ -5159,6 +5176,9 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
        mVisualStabilityManager.setScreenOn(true);
        mNotificationPanel.setTouchDisabled(false);
        updateVisibleToUser();
        if (mBurnInProtectionController != null) {
            mBurnInProtectionController.startShiftTimer(mBurnInProtectionEnabled);
        }
    }

    public void onScreenTurningOn() {
@@ -5570,6 +5590,17 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
            case LOCKSCREEN_MEDIA_METADATA:
                mShowMediaMetadata = newValue == null || Integer.parseInt(newValue) == 1;
                break;
            case SYSTEMUI_BURNIN_PROTECTION:
                mBurnInProtectionEnabled = newValue != null && Integer.parseInt(newValue) == 1;
                if (mBurnInProtectionController != null) {
                    if (mBurnInProtectionEnabled) {
                        mBurnInProtectionController.startShiftTimer(true);
                    } else {
                        // Forcefully disable it
                        mBurnInProtectionController.stopShiftTimer(true);
                    }
                }
                break;
            default:
                break;
        }
+27 −0
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
package com.android.systemui.statusbar.phone;

import android.content.Context;
import android.content.res.Resources;
import android.util.AttributeSet;
import android.util.EventLog;
import android.view.MotionEvent;
@@ -35,6 +36,13 @@ public class PhoneStatusBarView extends PanelBar {

    PhoneStatusBar mBar;

    private int mBasePaddingBottom;
    private int mBasePaddingLeft;
    private int mBasePaddingRight;
    private int mBasePaddingTop;

    private ViewGroup mStatusBarContents;

    boolean mIsFullyOpenedPanel = false;
    private final PhoneStatusBarTransitions mBarTransitions;
    private ScrimController mScrimController;
@@ -67,9 +75,28 @@ public class PhoneStatusBarView extends PanelBar {
        mScrimController = scrimController;
    }

    public void shiftStatusBarItems(int horizontalShift, int verticalShift) {
        if (mStatusBarContents == null) {
            return;
        }

        mStatusBarContents.setPaddingRelative(mBasePaddingLeft + horizontalShift,
                mBasePaddingTop + verticalShift,
                mBasePaddingRight + horizontalShift,
                mBasePaddingBottom - verticalShift);
        invalidate();
    }

    @Override
    public void onFinishInflate() {
        mBarTransitions.init();

        mStatusBarContents = (ViewGroup) findViewById(R.id.status_bar_contents);

        mBasePaddingLeft = mStatusBarContents.getPaddingStart();
        mBasePaddingTop = mStatusBarContents.getPaddingTop();
        mBasePaddingRight = mStatusBarContents.getPaddingEnd();
        mBasePaddingBottom = mStatusBarContents.getPaddingBottom();
    }

    @Override
+104 −0
Original line number Diff line number Diff line
/*
 * Copyright 2017 Paranoid Android
 * Copyright 2017 The LineageOS 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.systemui.statusbar.policy;

import android.content.Context;
import android.content.res.Resources;
import android.os.Handler;
import android.os.Looper;
import android.util.Log;

import com.android.systemui.R;
import com.android.systemui.statusbar.phone.NavigationBarView;
import com.android.systemui.statusbar.phone.PhoneStatusBarView;

public class BurnInProtectionController {
    private static final String TAG = "BurnInProtectionController";
    private static final boolean DEBUG = false;
    private static final long INTERVAL = 60000; // Milliseconds

    private int mHorizontalShift = 0;
    private int mVerticalShift = 0;
    private int mHorizontalDirection = 1;
    private int mVerticalDirection = 1;
    private int mNavigationBarHorizontalMaxShift;
    private int mNavigationBarVerticalMaxShift;
    private int mHorizontalMaxShift;
    private int mVerticalMaxShift;
    private long mShiftInterval;

    private final Handler mHandler = new Handler();
    private final Runnable mRunnable = () -> { 
            shiftItems(); 
            mHandler.postDelayed(this.mRunnable, INTERVAL);
    };

    private NavigationBarView mNavigationBarView;
    private PhoneStatusBarView mPhoneStatusBarView;

    private Context mContext;

    public BurnInProtectionController(Context context, PhoneStatusBarView phoneStatusBarView) {
        mContext = context;

        mPhoneStatusBarView = phoneStatusBarView;

        mHorizontalMaxShift = mContext.getResources()
                .getDimensionPixelSize(R.dimen.burnin_protection_horizontal_shift);
        // total of ((vertical_max_shift - 1) * 2) pixels can be moved
        mVerticalMaxShift = mContext.getResources()
                .getDimensionPixelSize(R.dimen.burnin_protection_vertical_shift) - 1;
    }

    public void setNavigationBarView(NavigationBarView navigationBarView) {
        mNavigationBarView = navigationBarView;
    }

    public void startShiftTimer(boolean enabled) {
        if (!enabled) return;
        mHandler.removeCallbacks(mRunnable);
        mHandler.postDelayed(mRunnable, INTERVAL);
        if (DEBUG) Log.d(TAG, "Started shift timer");
    }

    public void stopShiftTimer(boolean enabled) {
        if (!enabled) return;
        mHandler.removeCallbacks(mRunnable);
        if (DEBUG) Log.d(TAG, "Canceled shift timer");
    }

    private void shiftItems() {
        mHorizontalShift += mHorizontalDirection;
        if ((mHorizontalShift >=  mHorizontalMaxShift) ||
                (mHorizontalShift <= -mHorizontalMaxShift)) {
            mHorizontalDirection *= -1;
        }

        mVerticalShift += mVerticalDirection;
        if ((mVerticalShift >=  mVerticalMaxShift) ||
                (mVerticalShift <= -mVerticalMaxShift)) {
            mVerticalDirection *= -1;
        }

        mPhoneStatusBarView.shiftStatusBarItems(mHorizontalShift, mVerticalShift);
        if (mNavigationBarView != null) {
            mNavigationBarView.shiftNavigationBarItems(mHorizontalShift, mVerticalShift);
        }
        if (DEBUG) Log.d(TAG, "Shifting items\u2026");
    }
}