From ec3faec7371b689d65e8392ad82ce6e04c9ea111 Mon Sep 17 00:00:00 2001 From: liaohanqin Date: Tue, 14 May 2024 17:00:26 +0800 Subject: [PATCH] =?UTF-8?q?fix(airplane):=20=E4=BF=AE=E5=A4=8D=E9=A3=9E?= =?UTF-8?q?=E8=A1=8C=E6=A8=A1=E5=BC=8F=E7=8A=B6=E6=80=81=E4=B8=8D=E6=AD=A3?= =?UTF-8?q?=E7=A1=AE=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 部分设备的飞行模式开关采取的行为类似插拔usb外接设备,控制中心设置飞行 模式开关会控制soft block,开关物理飞行模式会直与控制中心状态形成竞态导 致soft block并未传达到usb设备时,该设备已经卸载。此修改只是优化,无法 解决快速开关问题。 Log: 修复飞行模式状态不正确问题 Bug: https://pms.uniontech.com/bug-view-254511.html Influence: 飞行模式 Change-Id: Icfa96446df73a86b171057759d0c087060acd5d8 --- system/airplane_mode/manager.go | 22 +++--- system/airplane_mode/rfkill.go | 120 ++++++++++++++++++++++---------- 2 files changed, 91 insertions(+), 51 deletions(-) diff --git a/system/airplane_mode/manager.go b/system/airplane_mode/manager.go index 31c96e3e7..cb1110c73 100644 --- a/system/airplane_mode/manager.go +++ b/system/airplane_mode/manager.go @@ -225,23 +225,19 @@ func (mgr *Manager) listenWirelessEnabled() { if !hasValue { return } - wifiAirplaneMode := !wifiEnable + // 硬件关闭时,开启wifi会先收到enable变为true 然后变为false + hardEnable, err := mgr.nmManager.WirelessHardwareEnabled().Get(0) + if err != nil { + logger.Warning(err) + } + wifiAirplaneMode := !wifiEnable || !hardEnable mgr.setPropWifiEnabled(wifiAirplaneMode) - mgr.config.SetBlocked(rfkillTypeWifi, wifiAirplaneMode) // 无法判断wifi是否为soft block + mgr.config.SetBlocked(rfkillTypeWifi, !wifiEnable) // 无法判断wifi是否为soft block mgr.btDevicesMu.RLock() defer mgr.btDevicesMu.RUnlock() - var enabled = false - if len(mgr.btRfkillDevices) > 0 { - enabled = wifiAirplaneMode && mgr.BluetoothEnabled - } else { - enabled = wifiAirplaneMode - } - mgr.setPropEnabled(enabled) - logger.Debug("refresh all blocked state:", enabled) - // 仅保存 soft block 的状态 - mgr.config.SetBlocked(rfkillTypeAll, mgr.Enabled) - err := mgr.config.SaveConfig() + mgr.updateAllState() + err = mgr.config.SaveConfig() if err != nil { logger.Warningf("save rfkill config file failed, err: %v", err) } diff --git a/system/airplane_mode/rfkill.go b/system/airplane_mode/rfkill.go index 70adfd46d..89a7f4b89 100644 --- a/system/airplane_mode/rfkill.go +++ b/system/airplane_mode/rfkill.go @@ -12,6 +12,7 @@ import ( "strconv" "strings" "syscall" + "time" ) var endian binary.ByteOrder = getByteOrder() @@ -77,6 +78,22 @@ func (mgr *Manager) listenRfkill() { logger.Warning("failed to read event info:", err) continue } + + if event.Typ == rfkillTypeWifi && + event.Hard != 0 && + event.Soft != 0 { + // 开启了hard block,就解除soft block + time.AfterFunc(100*time.Millisecond, func() { + mgr.btDevicesMu.Lock() + numBt := len(mgr.btRfkillDevices) + mgr.btDevicesMu.Unlock() + if numBt == 0 { + mgr.block(rfkillTypeAll, false) + } else { + mgr.block(rfkillTypeWifi, false) + } + }) + } mgr.handleBTRfkillEvent(event) } } @@ -121,6 +138,43 @@ func (mgr *Manager) initBTRfkillDevice() { } } +func (mgr *Manager) updateAllState() { + if mgr.hasNmWirelessDevices { + if len(mgr.btRfkillDevices) > 0 { + mgr.setPropEnabled(mgr.BluetoothEnabled && mgr.WifiEnabled) + } else { + mgr.setPropEnabled(mgr.WifiEnabled) + + } + } else if len(mgr.btRfkillDevices) > 0 { + mgr.setPropEnabled(mgr.BluetoothEnabled) + } else { + logger.Info("rfkill device is empty") + mgr.setPropEnabled(false) + } + + // 仅保存 soft block 的状态 + allSoftBlocked := false + states, err := getRfkillState(rfkillTypeWifi) + if err != nil { + logger.Warning(err) + allSoftBlocked = mgr.BluetoothEnabled && mgr.WifiEnabled + } else if mgr.WifiEnabled { + allSoftBlocked = mgr.BluetoothEnabled + } else { + // nm 无线控制关闭,可能是hard关闭,dde只控制soft。 + for _, v := range states { + if v.Soft != 0 { + allSoftBlocked = true + + } + } + } + + mgr.config.SetBlocked(rfkillTypeAll, allSoftBlocked) + logger.Debug("refresh all blocked state:", allSoftBlocked) +} + // 只处理bluetooth设备 func (mgr *Manager) handleBTRfkillEvent(event *RfkillEvent) { if event.Typ != rfkillTypeBT { @@ -130,6 +184,22 @@ func (mgr *Manager) handleBTRfkillEvent(event *RfkillEvent) { defer mgr.btDevicesMu.Unlock() if event.Op == rfkillOpDel { delete(mgr.btRfkillDevices, event.Index) + if event.Soft != 0 { + // 飞行模式开启的时候,如果rfkill有hard block, + // 解除 all soft block,让硬件接管。 + // FIXME: 优化 + time.AfterFunc(300*time.Millisecond, func() { + hardEnable, err := mgr.nmManager.WirelessHardwareEnabled().Get(0) + if err != nil { + logger.Warning(err) + } + + logger.Debug("wifi hardware status:", hardEnable) + if !hardEnable { + mgr.block(rfkillTypeAll, false) + } + }) + } } else { mgr.btRfkillDevices[event.Index] = device{ typ: rfkillTypeBT, @@ -152,18 +222,8 @@ func (mgr *Manager) handleBTRfkillEvent(event *RfkillEvent) { btSoftBlocked := btCnt == softBtBlockCnt mgr.setPropHasAirplaneMode(btCnt != 0 || mgr.hasNmWirelessDevices) mgr.setPropBluetoothEnabled(btBlocked && btCnt != 0) - logger.Debug("refresh bluetooth blocked state:", btBlocked) - if mgr.hasNmWirelessDevices { - mgr.setPropEnabled(btBlocked && mgr.WifiEnabled) - logger.Debug("refresh all blocked state:", btBlocked && mgr.WifiEnabled) - // 仅保存 soft block 的状态 - mgr.config.SetBlocked(rfkillTypeAll, btSoftBlocked && mgr.WifiEnabled) - } else { - mgr.setPropEnabled(btBlocked && btCnt != 0) - logger.Debug("refresh all blocked state:", btBlocked) - // 仅保存 soft block 的状态 - mgr.config.SetBlocked(rfkillTypeAll, btSoftBlocked) - } + mgr.updateAllState() + logger.Debug("refresh bluetooth blocked state:", btSoftBlocked) mgr.config.SetBlocked(rfkillTypeBT, btSoftBlocked) // save rfkill key event result to config file err := mgr.config.SaveConfig() @@ -199,32 +259,23 @@ func rfkillAction(typ rfkillType, action rfkillState) error { return nil } -type rfkillModuleState struct { - count int - blocked bool -} - -func getRfkillState(typ rfkillType) (rfkillModuleState, error) { - state := rfkillModuleState{ - count: 0, - blocked: true, - } +func getRfkillState(typ rfkillType) ([]*RfkillEvent, error) { + ret := []*RfkillEvent{} // open rfkill file file, err := os.Open("/dev/rfkill") if err != nil { logger.Warningf("cant open rfkill, err: %v", err) - return state, err + return ret, err } // close file defer file.Close() // get fd fd := int(file.Fd()) - defer syscall.Close(fd) // set non-block err = syscall.SetNonblock(fd, true) if err != nil { logger.Warningf("cant set non-block, err: %v", err) - return state, err + return ret, err } // create event action event := &RfkillEvent{ @@ -241,7 +292,7 @@ func getRfkillState(typ rfkillType) (rfkillModuleState, error) { break } logger.Warningf("read rfkill failed, err: %v", err) - return state, err + return ret, err } // unmarshal to event info := bytes.NewBuffer(buf) @@ -249,7 +300,7 @@ func getRfkillState(typ rfkillType) (rfkillModuleState, error) { err = binary.Read(info, endian, event) if err != nil { logger.Warningf("binary read rfkill failed, err: %v", err) - return state, err + return ret, err } // check type here // if type is all type, all type match @@ -258,16 +309,9 @@ func getRfkillState(typ rfkillType) (rfkillModuleState, error) { if typ != rfkillTypeAll && typ != event.Typ { continue } - // add count - state.count++ - // check block state - // if exist at least one device is non block, - // this module is blocked now - if event.Hard == 0 && event.Soft == 0 { - state.blocked = false - } - continue + + ret = append(ret, event) } - logger.Infof("module state: %v", state) - return state, nil + + return ret, nil }