199 lines
6.4 KiB
Markdown
199 lines
6.4 KiB
Markdown
|
# WiFi Keep Alive Design Document
|
||
|
|
||
|
## 1. Overview
|
||
|
|
||
|
This document describes the design of a WiFi keep-alive feature to prevent frequent WiFi disconnections in the robot application. The solution uses Android's WifiLock mechanism to keep the WiFi radio awake even when the device is idle.
|
||
|
|
||
|
## 2. Problem Statement
|
||
|
|
||
|
The robot application experiences frequent WiFi disconnections and reconnections, which affects its ability to maintain stable network communication. This issue impacts core functionalities that depend on continuous network connectivity.
|
||
|
|
||
|
## 3. Solution Approach
|
||
|
|
||
|
The solution involves implementing a WiFi keep-alive mechanism using Android's WifiLock API. This will prevent the WiFi radio from turning off when the device is idle, ensuring continuous network connectivity.
|
||
|
|
||
|
Key components of the solution:
|
||
|
- WiFiKeepAliveManager: Core class to manage WifiLock lifecycle
|
||
|
- Integration with existing network monitoring components
|
||
|
- Automatic WifiLock acquisition and release based on network state
|
||
|
|
||
|
## 4. Technical Design
|
||
|
|
||
|
### 4.1 Architecture
|
||
|
|
||
|
```mermaid
|
||
|
classDiagram
|
||
|
class WiFiKeepAliveManager {
|
||
|
- Context context
|
||
|
- WifiManager wifiManager
|
||
|
- WifiManager.WifiLock wifiLock
|
||
|
- NetworkStateMonitor networkMonitor
|
||
|
+ acquireWifiLock()
|
||
|
+ releaseWifiLock()
|
||
|
+ initialize()
|
||
|
+ destroy()
|
||
|
}
|
||
|
|
||
|
class NetworkStateMonitor {
|
||
|
- NetworkState currentState
|
||
|
+ registerNetworkCallback()
|
||
|
+ unregisterNetworkCallback()
|
||
|
+ getNetworkState()
|
||
|
}
|
||
|
|
||
|
class NetworkState {
|
||
|
<<enumeration>>
|
||
|
NO_NETWORK
|
||
|
MOBILE_CONNECTED
|
||
|
WIFI_CONNECTED
|
||
|
ETHERNET_CONNECTED
|
||
|
}
|
||
|
|
||
|
WiFiKeepAliveManager --> NetworkStateMonitor : uses
|
||
|
NetworkStateMonitor --> NetworkState : monitors
|
||
|
```
|
||
|
|
||
|
### 4.2 WiFiKeepAliveManager Implementation
|
||
|
|
||
|
The WiFiKeepAliveManager is responsible for managing the WifiLock lifecycle:
|
||
|
|
||
|
1. **Initialization**: Acquires WifiManager and creates WifiLock
|
||
|
2. **Network Monitoring**: Listens to network state changes
|
||
|
3. **WifiLock Management**: Acquires lock when WiFi is connected, releases when disconnected
|
||
|
4. **Resource Cleanup**: Properly releases resources when destroyed
|
||
|
|
||
|
### 4.3 Integration Points
|
||
|
|
||
|
The WiFi keep-alive feature will integrate with existing components:
|
||
|
- NetworkStateManager: For monitoring network state changes
|
||
|
- Application lifecycle: To properly initialize and destroy the keep-alive mechanism
|
||
|
|
||
|
## 5. Implementation Details
|
||
|
|
||
|
### 5.1 Required Permissions
|
||
|
|
||
|
Add the following permissions to AndroidManifest.xml:
|
||
|
```xml
|
||
|
<uses-permission android:name="android.permission.WAKE_LOCK" />
|
||
|
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
|
||
|
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
|
||
|
```
|
||
|
|
||
|
### 5.2 WiFiKeepAliveManager Class
|
||
|
|
||
|
```java
|
||
|
public class WiFiKeepAliveManager {
|
||
|
private static final String TAG = "WiFiKeepAliveManager";
|
||
|
private Context context;
|
||
|
private WifiManager wifiManager;
|
||
|
private WifiManager.WifiLock wifiLock;
|
||
|
private NetworkStateMonitor networkMonitor;
|
||
|
|
||
|
public WiFiKeepAliveManager(Context context) {
|
||
|
this.context = context.getApplicationContext();
|
||
|
this.wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
|
||
|
this.networkMonitor = new NetworkStateMonitor(context);
|
||
|
initializeWifiLock();
|
||
|
}
|
||
|
|
||
|
private void initializeWifiLock() {
|
||
|
if (wifiManager != null) {
|
||
|
// Create a high performance WiFi lock
|
||
|
wifiLock = wifiManager.createWifiLock(WifiManager.WIFI_MODE_FULL_HIGH_PERF, "RobotApp:WiFiKeepAlive");
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public void initialize() {
|
||
|
// Register for network state changes
|
||
|
networkMonitor.setNetworkStateCallback(new NetworkStateCallback() {
|
||
|
@Override
|
||
|
public void onNetworkStateChanged(NetworkState state) {
|
||
|
handleNetworkStateChange(state);
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public void onNetworkLost() {
|
||
|
releaseWifiLock();
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public void onNetworkAvailable() {
|
||
|
// Network available callback
|
||
|
}
|
||
|
});
|
||
|
|
||
|
networkMonitor.registerNetworkCallback();
|
||
|
}
|
||
|
|
||
|
private void handleNetworkStateChange(NetworkState state) {
|
||
|
if (state == NetworkState.WIFI_CONNECTED) {
|
||
|
acquireWifiLock();
|
||
|
} else {
|
||
|
releaseWifiLock();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public void acquireWifiLock() {
|
||
|
if (wifiLock != null && !wifiLock.isHeld()) {
|
||
|
try {
|
||
|
wifiLock.acquire();
|
||
|
Log.d(TAG, "WiFi lock acquired");
|
||
|
} catch (Exception e) {
|
||
|
Log.e(TAG, "Failed to acquire WiFi lock", e);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public void releaseWifiLock() {
|
||
|
if (wifiLock != null && wifiLock.isHeld()) {
|
||
|
try {
|
||
|
wifiLock.release();
|
||
|
Log.d(TAG, "WiFi lock released");
|
||
|
} catch (Exception e) {
|
||
|
Log.e(TAG, "Failed to release WiFi lock", e);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public void destroy() {
|
||
|
releaseWifiLock();
|
||
|
networkMonitor.unregisterNetworkCallback();
|
||
|
context = null;
|
||
|
wifiManager = null;
|
||
|
wifiLock = null;
|
||
|
}
|
||
|
}
|
||
|
```
|
||
|
|
||
|
### 5.3 Integration with Application Lifecycle
|
||
|
|
||
|
The WiFiKeepAliveManager should be initialized when the application starts and destroyed when the application is terminated:
|
||
|
|
||
|
1. **Initialization**: In Application onCreate() or main Activity onCreate()
|
||
|
2. **Destruction**: In Application onTerminate() or main Activity onDestroy()
|
||
|
|
||
|
## 6. Testing Strategy
|
||
|
|
||
|
### 6.1 Unit Tests
|
||
|
|
||
|
- Test WifiLock acquisition and release
|
||
|
- Test network state change handling
|
||
|
- Test proper resource cleanup
|
||
|
|
||
|
### 6.2 Integration Tests
|
||
|
|
||
|
- Verify WiFi stays connected during device idle periods
|
||
|
- Test behavior when switching between different network types
|
||
|
- Validate proper operation across different Android versions
|
||
|
|
||
|
## 7. Performance Considerations
|
||
|
|
||
|
1. **Battery Impact**: Using WifiLock will increase battery consumption as WiFi radio remains active
|
||
|
2. **Optimization**: Only acquire WifiLock when WiFi is connected, release when disconnected
|
||
|
3. **Android Version Compatibility**: Handle differences in WiFi management across Android versions
|
||
|
|
||
|
## 8. Error Handling
|
||
|
|
||
|
- Handle cases where WifiLock cannot be acquired
|
||
|
- Gracefully handle missing permissions
|
||
|
- Log errors for debugging and monitoring
|