Android 9.0系统-保持wifi 热点永不超时

正常逻辑:热点再没有连接的情况下,一段时间后会自动关闭

需求:启动热点后,保持热点长连接,不会自动关闭

思路:通过关闭热点函数,反向寻找 关闭热点的位置。

 

具体实现:

路径:Frameworks/opt/net/wifi/service/java/com/mediatek/server/wifi/MtkSoftApManager.java

关键点:

  • getValue()   //是否开启超时功能
  • getConfigSoftApTimeoutDelay()  //获取超时限制的时间
  • CMD_NO_ASSOCIATED_STATIONS_TIMEOUT //超时后触发消息,关闭热点 

我是偷懒,直接在消息触发后直接 break;这样永远就走不到关闭热点的逻辑

以下是热点开关的主要逻辑:

        private class StartedState extends State {
            private int mTimeoutDelay; //设置自动关闭热点时间
            private WakeupMessage mSoftApTimeoutMessage;
            private SoftApTimeoutEnabledSettingObserver mSettingObserver;

            /**
            * Observer for timeout settings changes.
            */
            private class SoftApTimeoutEnabledSettingObserver extends ContentObserver {
                SoftApTimeoutEnabledSettingObserver(Handler handler) {
                    super(handler);
                }

                public void register() {
                    mFrameworkFacade.registerContentObserver(mContext,
                            Settings.Global.getUriFor(Settings.Global.SOFT_AP_TIMEOUT_ENABLED),
                            true, this);
                    mTimeoutEnabled = getValue();//是否启用热点超时关闭功能
                }

                public void unregister() {
                    mFrameworkFacade.unregisterContentObserver(mContext, this);
                }

                @Override
                public void onChange(boolean selfChange) {
                    super.onChange(selfChange);
                    mStateMachine.sendMessage(SoftApStateMachine.CMD_TIMEOUT_TOGGLE_CHANGED,
                            getValue() ? 1 : 0);
                }

                private boolean getValue() {
                    boolean enabled = mFrameworkFacade.getIntegerSetting(mContext,
                            Settings.Global.SOFT_AP_TIMEOUT_ENABLED, 1) == 1;
                    return enabled;
                }
            }

            private int getConfigSoftApTimeoutDelay() {
                int delay = mContext.getResources().getInteger(
                        R.integer.config_wifi_framework_soft_ap_timeout_delay);
                if (delay < MIN_SOFT_AP_TIMEOUT_DELAY_MS) {
                    delay = MIN_SOFT_AP_TIMEOUT_DELAY_MS;
                    Log.w(TAG, "Overriding timeout delay with minimum limit value");
                }
                Log.d(TAG, "Timeout delay: " + delay);
                return delay; //返回timeout时间(默认10min)
            }

            private void scheduleTimeoutMessage() {
                if (!mTimeoutEnabled) {
                    return;
                }
                mSoftApTimeoutMessage.schedule(SystemClock.elapsedRealtime() + mTimeoutDelay);
                Log.d(TAG, "Timeout message scheduled");
            }

            private void cancelTimeoutMessage() {
                mSoftApTimeoutMessage.cancel();
                Log.d(TAG, "Timeout message canceled");
            }

            /**
             * Set number of stations associated with this soft AP
             * @param numStations Number of connected stations
             */
            private void setNumAssociatedStations(int numStations) {
                if (mNumAssociatedStations == numStations) {
                    return;
                }
                mNumAssociatedStations = numStations;
                Log.d(TAG, "Number of associated stations changed: " + mNumAssociatedStations);

                if (mCallback != null) {
                    mCallback.onNumClientsChanged(mNumAssociatedStations);
                } else {
                    Log.e(TAG, "SoftApCallback is null. Dropping NumClientsChanged event.");
                }
                mWifiMetrics.addSoftApNumAssociatedStationsChangedEvent(mNumAssociatedStations,
                        mMode);

                if (mNumAssociatedStations == 0) {
                    scheduleTimeoutMessage();
                } else {
                    cancelTimeoutMessage();
                }
            }

            private void onUpChanged(boolean isUp) {
                if (isUp == mIfaceIsUp) {
                    return;  // no change
                }
                mIfaceIsUp = isUp;
                if (isUp) {
                    Log.d(TAG, "SoftAp is ready for use");
                    updateApState(WifiManager.WIFI_AP_STATE_ENABLED,
                            WifiManager.WIFI_AP_STATE_ENABLING, 0);
                    mWifiMetrics.incrementSoftApStartResult(true, 0);
                    if (mCallback != null) {
                        mCallback.onNumClientsChanged(mNumAssociatedStations);
                    }
                } else {
                    // the interface was up, but goes down
                    sendMessage(CMD_INTERFACE_DOWN);
                }
                mWifiMetrics.addSoftApUpChangedEvent(isUp, mMode);
            }

            @Override
            public void enter() {
                mIfaceIsUp = false;
                onUpChanged(mWifiNative.isInterfaceUp(mApInterfaceName));

                mTimeoutDelay = getConfigSoftApTimeoutDelay();
                Handler handler = mStateMachine.getHandler();
                mSoftApTimeoutMessage = new WakeupMessage(mContext, handler,
                        SOFT_AP_SEND_MESSAGE_TIMEOUT_TAG,
                        SoftApStateMachine.CMD_NO_ASSOCIATED_STATIONS_TIMEOUT);
                mSettingObserver = new SoftApTimeoutEnabledSettingObserver(handler);

                if (mSettingObserver != null) {
                    mSettingObserver.register();
                }
                Log.d(TAG, "Resetting num stations on start");
                mNumAssociatedStations = 0;
                scheduleTimeoutMessage();

                // M: STA+SAP
                IntentFilter intentFilter = new IntentFilter();
                intentFilter.addAction(WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION);
                mContext.registerReceiver(mWifiP2pReceiver, intentFilter);
            }

            @Override
            public void exit() {
                if (mApInterfaceName != null) {
                    stopSoftAp();
                }
                if (mSettingObserver != null) {
                    mSettingObserver.unregister();
                }
                Log.d(TAG, "Resetting num stations on stop");
                mNumAssociatedStations = 0;
                cancelTimeoutMessage();
                // Need this here since we are exiting |Started| state and won't handle any
                // future CMD_INTERFACE_STATUS_CHANGED events after this point
                mWifiMetrics.addSoftApUpChangedEvent(false, mMode);
                updateApState(WifiManager.WIFI_AP_STATE_DISABLED,
                        WifiManager.WIFI_AP_STATE_DISABLING, 0);

                // M: Wi-Fi Hotspot Manager
                MtkWifiApMonitor.deregisterAllHandler();
                MtkWifiApMonitor.stopMonitoring(mApInterfaceName);
                synchronized (mHotspotClients) {
                    mHotspotClients.clear();
                }
                sendClientsChangedBroadcast();

                // M: STA+SAP
                mContext.unregisterReceiver(mWifiP2pReceiver);

                mApInterfaceName = null;
                mIfaceIsUp = false;
                mStateMachine.quitNow();
            }

            @Override
            public boolean processMessage(Message message) {
                switch (message.what) {
                    case CMD_NUM_ASSOCIATED_STATIONS_CHANGED:
                        if (message.arg1 < 0) {
                            Log.e(TAG, "Invalid number of associated stations: " + message.arg1);
                            break;
                        }
                        Log.d(TAG, "Setting num stations on CMD_NUM_ASSOCIATED_STATIONS_CHANGED");
                        setNumAssociatedStations(message.arg1);
                        break;
                    case CMD_SOFT_AP_CHANNEL_SWITCHED:
                        mReportedFrequency = message.arg1;
                        mReportedBandwidth = message.arg2;
                        Log.d(TAG, "Channel switched. Frequency: " + mReportedFrequency
                                + " Bandwidth: " + mReportedBandwidth);
                        mWifiMetrics.addSoftApChannelSwitchedEvent(mReportedFrequency,
                                mReportedBandwidth, mMode);
                        int[] allowedChannels = new int[0];
                        if (mApConfig.apBand == WifiConfiguration.AP_BAND_2GHZ) {
                            allowedChannels =
                                    mWifiNative.getChannelsForBand(WifiScanner.WIFI_BAND_24_GHZ);
                        } else if (mApConfig.apBand == WifiConfiguration.AP_BAND_5GHZ) {
                            allowedChannels =
                                    mWifiNative.getChannelsForBand(WifiScanner.WIFI_BAND_5_GHZ);
                        } else if (mApConfig.apBand == WifiConfiguration.AP_BAND_ANY) {
                            int[] allowed2GChannels =
                                    mWifiNative.getChannelsForBand(WifiScanner.WIFI_BAND_24_GHZ);
                            int[] allowed5GChannels =
                                    mWifiNative.getChannelsForBand(WifiScanner.WIFI_BAND_5_GHZ);
                            allowedChannels = Stream.concat(
                                    Arrays.stream(allowed2GChannels).boxed(),
                                    Arrays.stream(allowed5GChannels).boxed())
                                    .mapToInt(Integer::valueOf)
                                    .toArray();
                        }
                        if (!ArrayUtils.contains(allowedChannels, mReportedFrequency)) {
                            Log.e(TAG, "Channel does not satisfy user band preference: "
                                    + mReportedFrequency);
                            mWifiMetrics.incrementNumSoftApUserBandPreferenceUnsatisfied();
                        }
                        break;
                    case CMD_TIMEOUT_TOGGLE_CHANGED:
                        boolean isEnabled = (message.arg1 == 1);
                        if (mTimeoutEnabled == isEnabled) {
                            break;
                        }
                        mTimeoutEnabled = isEnabled;
                        if (!mTimeoutEnabled) {
                            cancelTimeoutMessage();
                        }
                        if (mTimeoutEnabled && mNumAssociatedStations == 0) {
                            scheduleTimeoutMessage();
                        }
                        break;
                    case CMD_INTERFACE_STATUS_CHANGED:
                        boolean isUp = message.arg1 == 1;
                        onUpChanged(isUp);
                        break;
                    case CMD_START:
                        // Already started, ignore this command.
                        break;
                    case CMD_NO_ASSOCIATED_STATIONS_TIMEOUT:
                        //偷懒直接break
                        //*/Timeout wifi_ap is disabled
                        if(true) {
                            Log.d(TAG, "cancel wifi soft AP timeout disable.");
                            break;
                        }
                        //*/

                        if (!mTimeoutEnabled) {
                            Log.wtf(TAG, "Timeout message received while timeout is disabled."
                                    + " Dropping.");
                            break;
                        }
                        if (mNumAssociatedStations != 0) {
                            Log.wtf(TAG, "Timeout message received but has clients. Dropping.");
                            break;
                        }
                        Log.i(TAG, "Timeout message received. Stopping soft AP.");
                        updateApState(WifiManager.WIFI_AP_STATE_DISABLING,
                                WifiManager.WIFI_AP_STATE_ENABLED, 0);
                        transitionTo(mIdleState);
                        break;
                    case CMD_INTERFACE_DESTROYED:
                        Log.d(TAG, "Interface was cleanly destroyed.");
                        updateApState(WifiManager.WIFI_AP_STATE_DISABLING,
                                WifiManager.WIFI_AP_STATE_ENABLED, 0);
                        mApInterfaceName = null;
                        transitionTo(mIdleState);
                        break;
                    case CMD_INTERFACE_DOWN:
                        Log.w(TAG, "interface error, stop and report failure");
                        updateApState(WifiManager.WIFI_AP_STATE_FAILED,
                                WifiManager.WIFI_AP_STATE_ENABLED,
                                WifiManager.SAP_START_FAILURE_GENERAL);
                        updateApState(WifiManager.WIFI_AP_STATE_DISABLING,
                                WifiManager.WIFI_AP_STATE_FAILED, 0);
                        transitionTo(mIdleState);
                        break;
                    // M: Wi-Fi Hotspot Manager
                    case CMD_POLL_IP_ADDRESS:
                        String deviceAddress = (String) message.obj;
                        int count = message.arg1;
                        String ipAddress =
                            mWifiManager.getWifiHotspotManager().getClientIp(deviceAddress);
                        String deviceName =
                            mWifiManager.getWifiHotspotManager().getClientDeviceName(deviceAddress);
                        Log.d(TAG, "CMD_POLL_IP_ADDRESS ,deviceAddress = " +
                              message.obj + " ipAddress = " + ipAddress + ", count = " + count);
                        if (ipAddress == null && count < POLL_IP_TIMES) {
                            sendMessageDelayed(CMD_POLL_IP_ADDRESS, ++count, 0, deviceAddress,
                                               POLL_IP_ADDRESS_INTERVAL_MSECS);
                        } else if (ipAddress != null) {
                            sendClientsIpReadyBroadcast(deviceAddress, ipAddress, deviceName);
                        }
                        break;
                    case MtkWifiApMonitor.AP_STA_CONNECTED_EVENT:
                        Log.d(TAG, "AP STA CONNECTED:" + message.obj);
                        String address = (String) message.obj;
                        synchronized (mHotspotClients) {
                            if (!mHotspotClients.containsKey(address)) {
                                mHotspotClients.put(address, new HotspotClient(address, false));
                            }
                        }

                        int start = 1;
                        sendMessageDelayed(CMD_POLL_IP_ADDRESS, start, 0, address,
                                           POLL_IP_ADDRESS_INTERVAL_MSECS);

                        sendClientsChangedBroadcast();
                        break;
                    case MtkWifiApMonitor.AP_STA_DISCONNECTED_EVENT:
                        Log.d(TAG, "AP STA DISCONNECTED:" + message.obj);
                        address = (String) message.obj;
                        synchronized (mHotspotClients) {
                            HotspotClient client = mHotspotClients.get(address);
                            if (client != null && !client.isBlocked) {
                                mHotspotClients.remove(address);
                            }
                        }

                        sendClientsChangedBroadcast();
                        break;
                    default:
                        return NOT_HANDLED;
                }
                return HANDLED;
            }
        }

Dear Vistor:

       感谢大家,如有更好的建议,留言哈。

 

  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
很抱歉,我无法提供关于"df -h"命令在Android 9.0上的输出。因为该命令用于查看文件系统的磁盘使用情况,而作为一个AI助手,我无法执行命令并提供实时的输出结果。但是,我可以告诉你一些关于Android 9.0的信息。 在Android 9.0中,进程管理方面相比Android 5.0有一些改变。Android 9.0引入了一种名为"Project Treble"的新架构,这使得系统和厂商定制的代码更加分离,使得系统更新更加容易和快速。这意味着在Android 9.0中,一些系统分区的内容可能被移动到了更加独立的分区,例如vendor.img分区,这是供厂商使用的一个分区,用于存储厂商定制的代码和驱动程序。 此外,Android 9.0还引入了更多的分区概念,例如动态分区(Dynamic Partitions)。动态分区允许系统根据需要动态调整分区大小,以便在不重新分区的情况下更新系统。这种分区方式可以提高系统更新的效率和速度[3]。 总之,Android 9.0在进程管理方面进行了一些改进,并引入了新的分区概念,以提高系统的灵活性和更新效率。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [Android 9.0 & 5.0 进程对比](https://blog.csdn.net/weixin_37927853/article/details/108947979)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* *3* [android 9.0 中关于OTA 升级的注意事项](https://blog.csdn.net/wed110/article/details/85691521)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值