# Pysical Tablet State Tablet mode is triggered when the laptop is reversed. We have checked how it is handled as a software. The tablet state in display::Screen stores the display tablet state. For example, when the laptop is reversed, but the tablet mode is disabled for some reasons, physical state is tablet but the display state is not tablet. Let's see how this physical layer event is handled in Chromium. ## Embedded Controller [Embedded Controller](https://chromium.googlesource.com/chromiumos/platform/ec/+/HEAD/README.md) a.k.a EC is a software to control lightweight, keyboard, battery charge, thermal and so on. The code is in [chromiumos/src/platform/ec](https://source.chromium.org/chromiumos/chromiumos/codesearch/+/main:src/platform/ec/). Tablet mode is also controlled by EC lid angle driver. The angle stands for how the display is closed, so it is the value that should be used to calculate whether the device is in tablet mode or clamshell mode. [AccelerometerReader](https://source.chromium.org/chromium/chromium/src/+/main:ash/accelerometer/accelerometer_reader.h;l=34;drc=42f0b9c4f60f67676d9096b3e94df9fd47f568f4) notifies EC lid angle driver availability and if it does not exist, it substitue the calculation logic instead of EC driver. ## TabletModeController [TabletModeController](https://source.chromium.org/chromium/chromium/src/+/main:ash/wm/tablet_mode/tablet_mode_controller.h;l=65;drc=4f20353c97007d9fe612b6406df7646d1a58c997) is responsible for listening to accelerometer events to enter/exit tablet mode when EC cannot hanlde lid angle calculation. [TabletModeController::SetIsInTabletPhysicalState](https://source.chromium.org/chromium/chromium/src/+/main:ash/wm/tablet_mode/tablet_mode_controller.cc;l=1370;drc=42f0b9c4f60f67676d9096b3e94df9fd47f568f4) updates the current phyisical state of the tablet mode and notiofy the observer including [AccelerometerProviderInterface::OnTabletPhysicalStateChanged](https://source.chromium.org/chromium/chromium/src/+/main:ash/accelerometer/accelerometer_reader.cc;l=58;drc=42f0b9c4f60f67676d9096b3e94df9fd47f568f4). Then if the device is in physically tablet, regardless of how it's displayed, it [TriggerRead](https://source.chromium.org/chromium/chromium/src/+/main:ash/accelerometer/accelerometer_reader.h;l=96;drc=42f0b9c4f60f67676d9096b3e94df9fd47f568f4). If the EC lid angle driver is supported, it continues to [EnableAccelerometerReading](https://source.chromium.org/chromium/chromium/src/+/main:ash/accelerometer/accelerometer_provider_mojo.cc;l=607;drc=42f0b9c4f60f67676d9096b3e94df9fd47f568f4) and force lid-accelerometer to be enabled. So how is TabletPhyicalState is set? It's updated on [LidEventReceived](https://source.chromium.org/chromium/chromium/src/+/main:ash/wm/tablet_mode/tablet_mode_controller.cc;l=701;drc=42f0b9c4f60f67676d9096b3e94df9fd47f568f4) and [TabletModeEventReceived](https://source.chromium.org/chromium/chromium/src/+/main:ash/wm/tablet_mode/tablet_mode_controller.cc;l=719;drc=42f0b9c4f60f67676d9096b3e94df9fd47f568f4) (there are several other as well e.g. configure, ForceUi...). It refers to [TabletModeBehavior](https://source.chromium.org/chromium/chromium/src/+/main:ash/wm/tablet_mode/tablet_mode_controller.h;l=225;drc=42f0b9c4f60f67676d9096b3e94df9fd47f568f4) data and how it should be forced by enum value of [ForcePysicalTabletState](https://source.chromium.org/chromium/chromium/src/+/main:ash/wm/tablet_mode/tablet_mode_controller.h;l=216;drc=42f0b9c4f60f67676d9096b3e94df9fd47f568f4). Both LidEvent and TabletModeEvent comes from [PowerManagerClient::InputEventReceived](https://source.chromium.org/chromium/chromium/src/+/main:chromeos/dbus/power/power_manager_client.cc;l=1252;drc=42f0b9c4f60f67676d9096b3e94df9fd47f568f4). dbus::Signal includes the type of the event as LID_OPEN, LID_CLOSED, TABLET_MODE_ON, TABLET_MODE_OFF ... There seems to be both cases where only lid state is sent or the tablet mode is directly sent with calculation being completed on dbus side. If TabletModeEvent is directly received, TabletModeController will just accept the event and set the physical state. If LidEvent is received, it checks LidState whether it is open.