[Samsung Galaxy J5 Guides, News, & Discussion] prototype74:
Hi guys, today I want to show you how you can enable Google's Night Light feature (which is available in AOSP based ROMs) for TW Nougat and Oreo ROMs! :)

But what's Night Light?

Night light tints our screen amber which make it easier for us to look at our display at night. It's similar to Samsung's Blue light filter which unfortunately not all Samsung galaxy devices (like my A3 2015) got it out of the box. Especially this guide is made for devices without blue light filter support.

Of course, this guide works for devices with BLF too but I see no reason to enable it there.

What's so special in Night Light?

Night light also supports our AMOLED screen panels. It won't overlay dark area on our screens which will keep it black (example with AOD in screenshots section below)

Guide structure:

- Post #1: Night Light on TW Nougat 7.1.1

- Post #2: Night Light on TW Oreo 8.0.0

- Post #3: Source view in Java language (N and O) for advanced users and developers

- Post #4: Credits

Requirements:

- Knowlegde about de-/recompile APKs (recommend to use TickleMyAndroid by [MENTION=4315551]Ticklefish[/MENTION] if you're not familiar with compiling APKs)

- A Texteditor like Notepad++ or Atom

- Know how Android .smali works

- Know how to make/read logcats, in case something didn't worked

- Patience (especially when it comes to recompile SecSettings2.apk)

- Last but not least, know what I'm talking about

Notes to developers:

Feel free to use this mod in your projects with a proper credit. Just keep in mind:

The following methods, variables etc. are NOT from any other galaxy device.

Some are from AOSP (adapted to TW) and some are coded by myself.

So you'll never find these in any other official TW ROM.

Now let's getting started ;)

How to enable Night light on Samsung Experience 8.5 (Android 7.1.1) Nougat ROMs

I've tested this on my A3 2015 with Nougat 7.1.1 only but might work for 7.0 too. Process with caution if you're on 7.0!

Part 1 - framework-res.apk

Decompile framework-res.apk and go to framework-res.apk/res/values/bools.xml.

Search for config_nightDisplayAvailable and change it's boolean from false to true:

<bool name="config_nightDisplayAvailable">true</bool>

Recompile framework-res.apk

Part 2 - SecSettings2.apk

2.1 Decompile SecSettings2.apk and go to SecSettings2.apk/smali/android/support/v7/preference/PreferenceCategory.smali. Now add these following constructors BEFORE #virtual methods:

[COLOR="Blue"]# direct methods
.method public constructor <init>(Landroid/content/Context;)V
.locals 1

const/4 v0, 0x0

invoke-direct {p0, p1, v0}, Landroid/support/v7/preference/PreferenceCategory;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;)V

return-void
.end method

.method public constructor <init>(Landroid/content/Context;Landroid/util/AttributeSet;)V
.locals 2

sget v0, Landroid/support/v7/preference/R$attr;->preferenceCategoryStyle:I

const v1, 0x101008c

invoke-static {p1, v0, v1}, Landroid/support/v4/content/res/TypedArrayUtils;->getAttr(Landroid/content/Context;II)I

move-result v0

invoke-direct {p0, p1, p2, v0}, Landroid/support/v7/preference/PreferenceCategory;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;I)V

return-void
.end method

.method public constructor <init>(Landroid/content/Context;Landroid/util/AttributeSet;I)V
.locals 1

const/4 v0, 0x0

invoke-direct {p0, p1, p2, p3, v0}, Landroid/support/v7/preference/PreferenceCategory;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;II)V

return-void
.end method

.method public constructor <init>(Landroid/content/Context;Landroid/util/AttributeSet;II)V
.locals 0

invoke-direct {p0, p1, p2, p3, p4}, Landroid/support/v7/preference/PreferenceGroup;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;II)V

return-void
.end method[/COLOR]

# virtual methods
.method public isEnabled()Z
.locals 1
...

2.2 Now go to SecSettings2.apk/smali/android/support/v7/preference/R$attr.smali and add blue static variable:

# static fields
.field public static final dialogPreferenceStyle:I = 0x7f010113

.field public static final dropdownPreferenceStyle:I = 0x7f010116

[COLOR="Blue"].field public static final preferenceCategoryStyle:I = [/COLOR][COLOR="Red"]0x7f01010e[/COLOR]

.field public static final preferenceFragmentStyle:I = 0x7f01010c

.field public static final preferenceScreenStyle:I = 0x7f01010a

...

0x7f01010e means you have to replace this resource with that from your Settings app. For this go to SecSettings2.apk/res/values/public.xml and search for preferenceCategoryStyle.

Get it's id and replace it with 0x7f01010e.

2.3 Now go to SecSettings2.apk/smali/com/android/settings/DisplaySettings.smali

Search for night_display and replace red line:

:goto_0
invoke-static {v0}, Lcom/android/internal/app/NightDisplayController;->isAvailable(Landroid/content/Context;)Z

move-result v10

if-nez v10, :cond_1

const-string/jumbo v10, "night_display"

[COLOR="Red"]invoke-virtual {p0, v10}, Lcom/android/settings/DisplaySettings;->removePreference(Ljava/lang/String;)V[/COLOR]

:cond_1
invoke-static {v0}, Lcom/android/settings/DisplaySettings;->isLiftToWakeAvailable(Landroid/content/Context;)Z

with blue lines:

:goto_0
invoke-static {v0}, Lcom/android/internal/app/NightDisplayController;->isAvailable(Landroid/content/Context;)Z

move-result v10

if-nez v10, :cond_1

const-string/jumbo v10, "night_display"

[COLOR="Blue"] invoke-virtual {p0, v10}, Lcom/android/settings/DisplaySettings;->findPreference(Ljava/lang/CharSequence;)Landroid/support/v7/preference/Preference;

move-result-object v10

check-cast v10, Landroid/support/v14/preference/SwitchPreference;

iput-object v10, p0, Lcom/android/settings/DisplaySettings;->mNightDisplayPreference:Landroid/support/v14/preference/SwitchPreference;

iget-object v10, p0, Lcom/android/settings/DisplaySettings;->mNightDisplayPreference:Landroid/support/v14/preference/SwitchPreference;

invoke-virtual {v10, p0}, Landroid/support/v14/preference/SwitchPreference;->setOnPreferenceChangeListener(Landroid/support/v7/preference/Preference$OnPreferenceChangeListener;)V[/COLOR]

:cond_1
invoke-static {v0}, Lcom/android/settings/DisplaySettings;->isLiftToWakeAvailable(Landroid/content/Context;)Z

2.3. This is the most important part. In this part we're adding new methods and variables to SecDisplaySettings.smali in order to make our switch preference (on/off) setting to work. Go to SecSettings2.apk/smali/com/samsung/android/settings/display/SecDisplaySettings.smali

We have to implement a new interface. Add blue line:

# interfaces
[COLOR="Blue"].implements Lcom/android/internal/app/NightDisplayController$Callback;[/COLOR]
.implements Landroid/preference/Preference$OnPreferenceChangeListener;
.implements Lcom/android/settings/search/Indexable;

Now we need 2 new variables to set our setting and calling it later in our methods. Add these variables to #instance fields:

#instance fields
...

[COLOR="blue"].field private mController:Lcom/android/internal/app/NightDisplayController;

.field private mNightDisplayPreference:Landroid/preference/SwitchPreference;[/COLOR]

...

So, now we have to add

5 new methods

in SecDisplaySettings.smali. These methods work together to enable and disable Night light:

[COLOR="blue"].method public onActivatedNightDisplay(Z)V
.locals 1

iget-object v0, p0, Lcom/samsung/android/settings/display/SecDisplaySettings;->mNightDisplayPreference:Landroid/preference/SwitchPreference;

invoke-virtual {v0, p1}, Landroid/preference/SwitchPreference;->setChecked(Z)V

return-void
.end method

.method public onCreateNightDisplay(Landroid/os/Bundle;)V
.locals 2

invoke-virtual {p0}, Lcom/samsung/android/settings/display/SecDisplaySettings;->getContext()Landroid/content/Context;

move-result-object v0

new-instance v1, Lcom/android/internal/app/NightDisplayController;

invoke-direct {v1, v0}, Lcom/android/internal/app/NightDisplayController;-><init>(Landroid/content/Context;)V

iput-object v1, p0, Lcom/samsung/android/settings/display/SecDisplaySettings;->mController:Lcom/android/internal/app/NightDisplayController;

return-void
.end method

.method public onStartNightDisplay()V
.locals 1

iget-object v0, p0, Lcom/samsung/android/settings/display/SecDisplaySettings;->mController:Lcom/android/internal/app/NightDisplayController;

invoke-virtual {v0, p0}, Lcom/android/internal/app/NightDisplayController;->setListener(Lcom/android/internal/app/NightDisplayController$Callback;)V

iget-object v0, p0, Lcom/samsung/android/settings/display/SecDisplaySettings;->mController:Lcom/android/internal/app/NightDisplayController;

invoke-virtual {v0}, Lcom/android/internal/app/NightDisplayController;->isActivated()Z

move-result v0

invoke-virtual {p0, v0}, Lcom/samsung/android/settings/display/SecDisplaySettings;->onActivatedNightDisplay(Z)V

return-void
.end method

.method public onStopNightDisplay()V
.locals 2

iget-object v0, p0, Lcom/samsung/android/settings/display/SecDisplaySettings;->mController:Lcom/android/internal/app/NightDisplayController;

const/4 v1, 0x0

invoke-virtual {v0, v1}, Lcom/android/internal/app/NightDisplayController;->setListener(Lcom/android/internal/app/NightDisplayController$Callback;)V

return-void
.end method

.method public onPreferenceNightDisplayChange(Landroid/preference/Preference;Ljava/lang/Object;)V
.locals 3

iget-object v0, p0, Lcom/samsung/android/settings/display/SecDisplaySettings;->mNightDisplayPreference:Landroid/preference/SwitchPreference;

if-ne p1, v0, :cond_0

invoke-virtual {p0}, Lcom/samsung/android/settings/display/SecDisplaySettings;->getContentResolver()Landroid/content/ContentResolver;

move-result-object v1

const-string v2, "night_display_activated"

check-cast p2, Ljava/lang/Boolean;

invoke-virtual {p2}, Ljava/lang/Boolean;->booleanValue()Z

move-result v0

if-eqz v0, :cond_1

const/4 v0, 0x1

:goto_0
invoke-static {v1, v2, v0}, Landroid/provider/Settings$Secure;->putInt(Landroid/content/ContentResolver;Ljava/lang/String;I)Z

:cond_0
return-void

:cond_1
const/4 v0, 0x0

goto :goto_0
.end method[/COLOR]

Now we have added these methods but none call them. In order to make them working we have to call them in already existing methods in SecDisplaySettings.smali

Search for

[B].method public onCreate(Landroid/os/Bundle;)V[/B]

and add blue line:

.method public onCreate(Landroid/os/Bundle;)V
.locals 31

invoke-super/range {p0 .. p1}, Lcom/samsung/android/settings/SecSettingsPreferenceFragment;->onCreate(Landroid/os/Bundle;)V

[COLOR="Blue"] invoke-virtual/range {p0 .. p1}, Lcom/samsung/android/settings/display/SecDisplaySettings;->onCreateNightDisplay(Landroid/os/Bundle;)V[/COLOR]

...

in same method scroll down until you reached end of method (.end method)

It should look something like this:

...

if-eqz v27, :cond_44

move-object/from16 v0, p0

iget-object v0, v0, Lcom/samsung/android/settings/display/SecDisplaySettings;->mAutoBrightnessPreferenceNoPAC:Landroid/preference/SwitchPreference;

move-object/from16 v27, v0

move-object/from16 v0, v27

move-object/from16 v1, p0

invoke-virtual {v0, v1}, Landroid/preference/SwitchPreference;->setOnPreferenceChangeListener(Landroid/preference/Preference$OnPreferenceChangeListener;)V

invoke-direct/range {p0 .. p0}, Lcom/samsung/android/settings/display/SecDisplaySettings;->updateAutoBrightness()V

goto/16 :goto_24

[COLOR="Red"]:cond_58[/COLOR]
const-string/jumbo v27, "screen_timeout_for_dex"

move-object/from16 v0, p0

move-object/from16 v1, v27

invoke-virtual {v0, v1}, Lcom/samsung/android/settings/display/SecDisplaySettings;->removePreference(Ljava/lang/String;)V

goto/16 :goto_25
.end method

Replace :cond_58 with blue lines:

if-eqz v27, :cond_44

move-object/from16 v0, p0

iget-object v0, v0, Lcom/samsung/android/settings/display/SecDisplaySettings;->mAutoBrightnessPreferenceNoPAC:Landroid/preference/SwitchPreference;

move-object/from16 v27, v0

move-object/from16 v0, v27

move-object/from16 v1, p0

invoke-virtual {v0, v1}, Landroid/preference/SwitchPreference;->setOnPreferenceChangeListener(Landroid/preference/Preference$OnPreferenceChangeListener;)V

invoke-direct/range {p0 .. p0}, Lcom/samsung/android/settings/display/SecDisplaySettings;->updateAutoBrightness()V

goto/16 :goto_24

[COLOR="Blue"] :cond_58
const-string/jumbo v27, "night_display_activated"

move-object/from16 v0, p0

move-object/from16 v1, v27

invoke-virtual {v0, v1}, Lcom/samsung/android/settings/display/SecDisplaySettings;->findPreference(Ljava/lang/CharSequence;)Landroid/preference/Preference;

move-result-object v27

check-cast v27, Landroid/preference/SwitchPreference;

move-object/from16 v0, v27

move-object/from16 v1, p0

iput-object v0, v1, Lcom/samsung/android/settings/display/SecDisplaySettings;->mNightDisplayPreference:Landroid/preference/SwitchPreference;

move-object/from16 v0, p0

iget-object v0, v0, Lcom/samsung/android/settings/display/SecDisplaySettings;->mNightDisplayPreference:Landroid/preference/SwitchPreference;

move-object/from16 v27, v0

if-eqz v27, :cond_59

move-object/from16 v0, p0

iget-object v0, v0, Lcom/samsung/android/settings/display/SecDisplaySettings;->mNightDisplayPreference:Landroid/preference/SwitchPreference;

move-object/from16 v27, v0

move-object/from16 v0, v27

move-object/from16 v1, p0

invoke-virtual {v0, v1}, Landroid/preference/SwitchPreference;->setOnPreferenceChangeListener(Landroid/preference/Preference$OnPreferenceChangeListener;)V

invoke-virtual {v1}, Lcom/samsung/android/settings/display/SecDisplaySettings;->onStartNightDisplay()V

:cond_59[/COLOR]
const-string/jumbo v27, "screen_timeout_for_dex"

move-object/from16 v0, p0

move-object/from16 v1, v27

invoke-virtual {v0, v1}, Lcom/samsung/android/settings/display/SecDisplaySettings;->removePreference(Ljava/lang/String;)V

goto/16 :goto_25
.end method

Search for

.method public onPause()V

and add blue line:

.method public onPause()V
.locals 2

invoke-super {p0}, Lcom/samsung/android/settings/SecSettingsPreferenceFragment;->onPause()V

[COLOR="Blue"]invoke-virtual {p0}, Lcom/samsung/android/settings/display/SecDisplaySettings;->onStopNightDisplay()V[/COLOR]

...
.end method

At last, search for

[B].method public onPreferenceChange(Landroid/preference/Preference;Ljava/lang/Object;)Z[/B]

and add blue line:

.method public onPreferenceChange(Landroid/preference/Preference;Ljava/lang/Object;)Z
.locals 38

[COLOR="blue"] invoke-virtual/range {p0 .. p2}, Lcom/samsung/android/settings/display/SecDisplaySettings;->onPreferenceNightDisplayChange(Landroid/preference/Preference;Ljava/lang/Object;)V[/COLOR]

....
.end method

Now we're finally done with SecDisplaySettings.smali :laugh:

2.4 We need to call onPreferenceNightDisplayChange in an another smali too. Go to SecSettings2.apk/smali/com/samsung/android/settings/display/SecDisplaySettings$19.smali

Search for

invoke-virtual {v0, v1, v14}, Lcom/samsung/android/settings/display/SecDisplaySettings;->onPreferenceChange(Landroid/preference/Preference;Ljava/lang/Object;)Z

And add blue line:

...

move-object/from16 v1, v23

invoke-virtual {v0, v1, v14}, Lcom/samsung/android/settings/display/SecDisplaySettings;->onPreferenceChange(Landroid/preference/Preference;Ljava/lang/Object;)Z
[COLOR="Blue"]
invoke-virtual {v0, v1, v14}, Lcom/samsung/android/settings/display/SecDisplaySettings;->onPreferenceNightDisplayChange(Landroid/preference/Preference;Ljava/lang/Object;)V[/COLOR]

move-object/from16 v0, p0

iget-object v0, v0, Lcom/samsung/android/settings/display/SecDisplaySettings$19;->this$0:Lcom/samsung/android/settings/display/SecDisplaySettings;

...

2.5 So now it's time for editing xml files. Go to SecSettings2.apk/res/xml/night_display_settings.xml.

It should look something like this:

<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen android:title="@string/night_display_title"
xmlns:android="http://schemas.android.com/apk/res/android" xmlns:settings="http://schemas.android.com/apk/res-auto">
<PreferenceCategory android:title="@string/night_display_category_schedule">
<DropDownPreference android:title="@string/night_display_auto_mode_title" android:key="night_display_auto_mode" android:summary="%s" />
<Preference android:title="@string/night_display_start_time_title" android:key="night_display_start_time" />
<Preference android:title="@string/night_display_end_time_title" android:key="night_display_end_time" />
</PreferenceCategory>
<PreferenceCategory android:title="@string/night_display_category_status">
<com.android.settings.display.NightDisplayPreference android:title="@string/night_display_title" android:key="night_display_activated" />
</PreferenceCategory>
<com.android.settings.fuelgauge.WallOfTextPreference android:selectable="false" android:summary="@string/night_display_text" settings:allowDividerAbove="true" />
</PreferenceScreen>

Replace <PreferenceScreen>...</PreferenceScreen> to this:

<?xml version="1.0" encoding="utf-8"?>
[COLOR="blue"]<PreferenceScreen android:title="@string/night_display_title"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:settings="http://schemas.android.com/apk/res/com.android.settings">
<PreferenceCategory android:title="@string/night_display_category_schedule" />
<DropDownPreference android:title="@string/night_display_auto_mode_title" android:key="night_display_auto_mode" android:summary="%s" />
<Preference android:title="@string/night_display_start_time_title" android:key="night_display_start_time" />
<Preference android:title="@string/night_display_end_time_title" android:key="night_display_end_time" />
<PreferenceCategory android:title="@string/night_display_category_status" />
<com.android.settings.display.NightDisplayPreference android:title="@string/night_display_title" android:key="night_display_activated" />
</PreferenceScreen>[/COLOR]

2.6 Finally we'll add our new switch preference setting to display settings. Go to SecSettings2.apk/res/xml/sec_display_settings.xml and add blue line:

...
<com.android.settings.SecSettingsSwitchPreference android:title="@string/auto_adjust_brightness" android:key="auto_brightness" android:summary="@string/auto_adjust_brightness_summary" android:fragment="com.samsung.android.settings.display.AutoBrightness" />
<SwitchPreference android:title="@string/outdoor_mode_title" android:key="outdoor_mode" android:summary="@string/outdoor_mode_summary" />
<com.samsung.android.settings.display.DisplayDisabledAppearanceSwitchPreference android:title="@string/blue_light_filter_title" android:key="blue_light_filter" android:summary="@string/blue_light_filter_summary_off" />
[COLOR="Blue"] <SwitchPreference android:title="@string/night_display_title" android:key="night_display_activated" android:summary="@string/night_display_text" />[/COLOR]
<PreferenceScreen android:title="@string/wallpaper" android:key="wallpaper">
<intent android:targetPackage="com.sec.android.app.wallpaperchooser" android:action="android.intent.action.MAIN" android:targetClass="com.sec.android.app.wallpaperchooser.WallpaperPickerActivity" />
</PreferenceScreen>
<SwitchPreference android:title="@string/display_auto_rotate_title" android:key="auto_rotate" />
<com.samsung.android.settings.display.DisplayDisabledAppearancePreference android:title="@string/display_scaling_title" android:key="display_scaling" />
...

Recompile SecSettings2.apk

Part 3 - Add Night light tile to quick settings (OPTIONAL)

There are different ways to add night light to quick settings. I would recommend option 1 or 2 as option 3 is resetable.

Option 1: SystemUI.apk

Decompile SystemUI.apk and go to SystemUI.apk/res/values/string.xml.

Search for quick_settings_tiles_default and add NightDisplay to it's string.

Example:

<string name="quick_settings_tiles_default">[COLOR="Blue"]NightDisplay[/COLOR],Wifi,SilentMode,Bluetooth,RotationLock,Flashlight,...</string>

Recompile SystemUI.apk

Option 2: CSC/OMC

Go to system/csc/others.xml and add NightDisplay to CscFeature_SystemUI_ConfigDefQuickSettingItem

Example:

<CscFeature_SystemUI_ConfigDefQuickSettingItem>[COLOR="Blue"]NightDisplay[/COLOR],Wifi,SilentMode,Bluetooth,RotationLock,Flashlight,...</CscFeature_SystemUI_ConfigDefQuickSettingItem>

If you have OMC instead, I recommend you to check out [GUIDE][Dev-Only] OMC/ODM manipulation tips and tricks by [MENTION=4658360]corsicanu[/MENTION] :)

Option 3: ADB

If you have adb installed run this command:

adb shell settings put secure sysui_qs_tiles "$(settings get secure sysui_qs_tiles),[COLOR="Blue"]NightDisplay[/COLOR]"

where $(settings get secure sysui_qs_tiles) means to get your current quick tiles.

Enjoy Night Light on Nougat :good: