nx: devicesettings: Refactor dockservice
Completely redo DockService to: - Work around NVIDIA hwcomposer issues - Properly support docking - Actually use set display preferences Change-Id: Ic1ea73c113f291bcbe40ecd4ecca3288c88368b4
This commit is contained in:
1 parent
c48f464980
commit
6ff57aca6a
5 files changed
+64
-65
No files matched your search
@@ -27,4 +27,7 @@
|
||||
<string name="mode_confirmation_summary">Are you sure you want to keep these display settings?\n\nWill revert in %1$d seconds</string>
|
||||
<string name="panel_color_setting_title">Select OLED Panel Color Mode</string>
|
||||
<string name="panel_color_setting_summary">Current mode: %s</string>
|
||||
<string name="disable_internal_on_external_connected_title">Turn off when an external display is connected</string>
|
||||
<string name="disable_internal_on_external_connected_summary_on">The internal panel will be turned off when an external display is connected</string>
|
||||
<string name="disable_internal_on_external_connected_summary_off">Both the internal panel and external display will show the same image</string>
|
||||
</resources>
|
||||
@@ -110,14 +110,14 @@ public class DisplaySettingsFragment extends PreferenceFragment
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getContext());
|
||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getActivity());
|
||||
prefs.registerOnSharedPreferenceChangeListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPause() {
|
||||
super.onPause();
|
||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getContext());
|
||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getActivity());
|
||||
prefs.unregisterOnSharedPreferenceChangeListener(this);
|
||||
}
|
||||
|
||||
@@ -144,6 +144,12 @@ public class DisplaySettingsFragment extends PreferenceFragment
|
||||
performModeChange(sharedPrefs, key, modeIndex, display);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (key.equals("disable_internal_on_external_connected")) {
|
||||
DisplayUtils.setInternalDisplayState(!(((DisplaySettingsActivity)getActivity()).mExternalDisplayConnected && sharedPrefs.getBoolean(key, false)));
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -407,5 +413,16 @@ public class DisplaySettingsFragment extends PreferenceFragment
|
||||
modesPreference.setValue(String.valueOf(currentMode.index));
|
||||
|
||||
category.addPreference(modesPreference);
|
||||
|
||||
// Show checkbox to disable internal panel when an external display is connected
|
||||
if (display == HwcSvcDisplay.HWC_SVC_DISPLAY_PANEL) {
|
||||
SwitchPreference disableInternalOnExternalConnectedPreference = new SwitchPreference(category.getContext());
|
||||
disableInternalOnExternalConnectedPreference.setTitle(R.string.disable_internal_on_external_connected_title);
|
||||
disableInternalOnExternalConnectedPreference.setSummaryOn(R.string.disable_internal_on_external_connected_summary_on);
|
||||
disableInternalOnExternalConnectedPreference.setSummaryOff(R.string.disable_internal_on_external_connected_summary_off);
|
||||
disableInternalOnExternalConnectedPreference.setKey("disable_internal_on_external_connected");
|
||||
|
||||
category.addPreference(disableInternalOnExternalConnectedPreference);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -16,8 +16,11 @@
|
||||
|
||||
package org.lineageos.settings.device;
|
||||
|
||||
import android.content.SharedPreferences;
|
||||
import android.hardware.display.DisplayManager;
|
||||
import android.os.RemoteException;
|
||||
import android.util.Log;
|
||||
import android.view.IWindowManager;
|
||||
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.FileInputStream;
|
||||
@@ -53,6 +56,24 @@ public class DisplayUtils {
|
||||
}
|
||||
}
|
||||
|
||||
public static void setDisplayMode(int display, INvDisplay displayService, IWindowManager windowManager, SharedPreferences sharedPrefs) {
|
||||
int index = 0; // default 0 for internal
|
||||
|
||||
try {
|
||||
// grab pref for external displays
|
||||
if(display > 0) {
|
||||
String displayUid = String.valueOf(DisplayUtils.makeDisplayLabel(displayService.edidGetInfo(display), display).hashCode());
|
||||
index = Integer.parseInt(sharedPrefs.getString(("mode_" + displayUid), "0"));
|
||||
}
|
||||
|
||||
// manually set hwc mode and force android to update rotation
|
||||
displayService.modeSetIndex(display, index);
|
||||
windowManager.updateRotation(true, true);
|
||||
} catch(RemoteException e) {
|
||||
Log.e(TAG, "Failed to set mode!");
|
||||
}
|
||||
}
|
||||
|
||||
public static HashMap<String, Integer> makeUidMap(INvDisplay displayService) {
|
||||
HashMap<String, Integer> uidMap = new HashMap<String, Integer>();
|
||||
for (int i = HwcSvcDisplay.HWC_SVC_DISPLAY_PANEL; i <= HwcSvcDisplay.HWC_SVC_DISPLAY_HDMI2; i++) {
|
||||
|
||||
@@ -29,6 +29,7 @@ import android.os.Parcel;
|
||||
import android.os.RemoteException;
|
||||
import android.os.ServiceManager;
|
||||
import android.os.UserHandle;
|
||||
import android.preference.PreferenceManager;
|
||||
import android.util.Log;
|
||||
import android.view.IWindowManager;
|
||||
import android.view.WindowManagerPolicyConstants;
|
||||
@@ -40,6 +41,8 @@ import java.io.IOException;
|
||||
import com.nvidia.NvAppProfiles;
|
||||
import com.nvidia.NvConstants;
|
||||
|
||||
import vendor.nvidia.hardware.graphics.display.V1_0.INvDisplay;
|
||||
|
||||
public class DockService extends Service {
|
||||
private static final String TAG = DockService.class.getSimpleName();
|
||||
private static final String NVCPL_SERVICE_KEY = "nvcpl";
|
||||
@@ -49,6 +52,7 @@ public class DockService extends Service {
|
||||
final private Receiver mReceiver = new Receiver();
|
||||
final private NvAppProfiles mAppProfiles = new NvAppProfiles(this);
|
||||
private DisplayManager mDisplayManager;
|
||||
private INvDisplay mDisplayService;
|
||||
private IWindowManager mWindowManager;
|
||||
private boolean isTv;
|
||||
|
||||
@@ -63,6 +67,13 @@ public class DockService extends Service {
|
||||
mDisplayManager = (DisplayManager) getSystemService(Context.DISPLAY_SERVICE);
|
||||
mWindowManager = IWindowManager.Stub.asInterface(ServiceManager.getService(Context.WINDOW_SERVICE));
|
||||
isTv = getPackageManager().hasSystemFeature(PackageManager.FEATURE_LEANBACK);
|
||||
|
||||
try {
|
||||
mDisplayService = INvDisplay.getService(true /* retry */);
|
||||
} catch (RemoteException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
mReceiver.init();
|
||||
|
||||
return super.onStartCommand(intent, flags, startId);
|
||||
@@ -70,8 +81,6 @@ public class DockService extends Service {
|
||||
|
||||
final class Receiver extends BroadcastReceiver {
|
||||
private boolean mExternalDisplayConnected = false;
|
||||
private int oldDisplayWidth = 1280;
|
||||
private int oldDisplayHeight = 720;
|
||||
|
||||
private void setFanProfile(String profile) {
|
||||
try {
|
||||
@@ -136,67 +145,16 @@ public class DockService extends Service {
|
||||
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
SharedPreferences sharedPrefs = context.getSharedPreferences("org.lineageos.settings.device_preferences", context.MODE_PRIVATE);
|
||||
final String action = intent.getAction();
|
||||
final boolean connected = intent.getBooleanExtra(WindowManagerPolicyConstants.EXTRA_HDMI_PLUGGED_STATE, false);
|
||||
|
||||
switch (action) {
|
||||
case WindowManagerPolicyConstants.ACTION_HDMI_PLUGGED:
|
||||
Log.i(TAG, "HDMI state update");
|
||||
|
||||
final boolean connected = intent.getBooleanExtra(WindowManagerPolicyConstants.EXTRA_HDMI_PLUGGED_STATE, false);
|
||||
|
||||
// Force docked display size to avoid apps being forced to the resolution of the internal panel
|
||||
try {
|
||||
if (connected) {
|
||||
if (isTv) {
|
||||
// On ATV always force 1080p for UI when docked, external display also always uses id 0
|
||||
mWindowManager.setForcedDisplaySize(0, 1920, 1080);
|
||||
mWindowManager.setForcedDisplayDensityForUser(0, 320, UserHandle.USER_CURRENT);
|
||||
} else {
|
||||
android.view.Display[] displays = mDisplayManager.getDisplays(DisplayManager.DISPLAY_CATEGORY_PRESENTATION);
|
||||
if (displays == null || displays.length == 0) {
|
||||
Log.e(TAG, "Failed to get available displays");
|
||||
return;
|
||||
}
|
||||
final int externalDisplayId = displays[0].getDisplayId();
|
||||
final Point displaySize = new Point();
|
||||
|
||||
for (int i = 0; i < displays.length; i++)
|
||||
Log.i(TAG, "Display idx: " + String.valueOf(i) + " id: " + String.valueOf(displays[i].getDisplayId()));
|
||||
|
||||
// Preserve user/default set built-in display resolution.
|
||||
mWindowManager.getBaseDisplaySize(0, displaySize);
|
||||
oldDisplayWidth = displaySize.x;
|
||||
oldDisplayHeight = displaySize.y;
|
||||
|
||||
// Scale built-in display to new resolution for smooth transition
|
||||
mWindowManager.getInitialDisplaySize(externalDisplayId, displaySize);
|
||||
mWindowManager.setForcedDisplaySize(0, displaySize.x, displaySize.y);
|
||||
|
||||
// Set new resolution to external display also.
|
||||
mWindowManager.setForcedDisplaySize(externalDisplayId, displaySize.x, displaySize.y);
|
||||
|
||||
// Set density based off standard 32" TV (1920x1080 @ 160dpi)
|
||||
mWindowManager.setForcedDisplayDensityForUser(externalDisplayId, 160, UserHandle.USER_CURRENT);
|
||||
}
|
||||
} else {
|
||||
Log.i(TAG, "HDMI disconnected");
|
||||
if (mExternalDisplayConnected) {
|
||||
if (isTv) {
|
||||
// Restore default resolution and density for built-in display
|
||||
mWindowManager.clearForcedDisplaySize(0);
|
||||
mWindowManager.clearForcedDisplayDensityForUser(0, UserHandle.USER_CURRENT);
|
||||
} else {
|
||||
// Restore user/default resolution back to built-in display
|
||||
mWindowManager.setForcedDisplaySize(0, oldDisplayWidth, oldDisplayHeight);
|
||||
}
|
||||
} else {
|
||||
// Restore user/default resolution back to built-in display
|
||||
mWindowManager.setForcedDisplaySize(0, oldDisplayWidth, oldDisplayHeight);
|
||||
}
|
||||
}
|
||||
} catch (RemoteException ex) {
|
||||
Log.w(TAG, "Failed to set display resolution");
|
||||
}
|
||||
if(mExternalDisplayConnected)
|
||||
DisplayUtils.setDisplayMode(1, mDisplayService, mWindowManager, sharedPrefs);
|
||||
else
|
||||
DisplayUtils.setDisplayMode(0, mDisplayService, mWindowManager, sharedPrefs);
|
||||
|
||||
mExternalDisplayConnected = connected;
|
||||
|
||||
@@ -205,19 +163,19 @@ public class DockService extends Service {
|
||||
case Intent.ACTION_SCREEN_ON:
|
||||
Log.i(TAG, "Screen on");
|
||||
|
||||
DisplayUtils.setInternalDisplayState(!mExternalDisplayConnected);
|
||||
DisplayUtils.setInternalDisplayState(!(mExternalDisplayConnected && sharedPrefs.getBoolean("disable_internal_on_external_connected", false)));
|
||||
|
||||
// Unlock device automatically if docked and reset res otherwise to work around broken HWC rotation
|
||||
try {
|
||||
if (mExternalDisplayConnected) {
|
||||
mWindowManager.dismissKeyguard(null, null);
|
||||
} else {
|
||||
mWindowManager.clearForcedDisplaySize(0);
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
Log.w(TAG, "Failed to dismiss keyguard and reset resolution");
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case DisplayUtils.POWER_UPDATE_INTENT:
|
||||
case Intent.ACTION_USER_PRESENT:
|
||||
updatePowerState(context, mExternalDisplayConnected);
|
||||
|
||||
+1
-1
@@ -12,7 +12,7 @@ PRODUCT_SYSTEM_PROPERTY_OVERRIDES += \
|
||||
|
||||
# HWC
|
||||
PRODUCT_PROPERTY_OVERRIDES += \
|
||||
persist.vendor.tegra.stb.mode=1
|
||||
persist.vendor.tegra.stb.mode=0
|
||||
|
||||
# USB configfs
|
||||
PRODUCT_PROPERTY_OVERRIDES += \
|
||||
|
||||
Reference in new issue
Block a user