Uses the application context instead of the activity context when updating the widget. This avoids leaking the activity instance if the update operation outlives the configuration screen.
Enhances robustness by adding extensive error handling around broadcast receiver registration, profile event processing, and service disconnections to prevent crashes. Also ensures device flow is cleared when Bluetooth is disabled.
Convert `connectedDevices()` from a function returning a cold Flow to a property that is a hot `StateFlow`. This simplifies call sites and improves efficiency by sharing the underlying subscription.
Switched from monitoring generic ACL events to specific Headset profile state changes for more reliable device connection and disconnection detection.
This fixes a race condition where CAPod thinks no device is connected because we triggered too early, before "connectedDevices" on the HEADSET profile contains our target device.
This fixes#313
This commit updates translations for German, Spanish, and Catalan. It also adds a comprehensive set of new strings for the Chinese (Simplified) localization.
Explains that single-pod detection is an Apple limitation, not an app bug.
Users experiencing this issue will now understand it only affects the
"primary pod" (microphone pod) and can be configured in iOS settings.
Closes#38, Closes#329
- Migrate ProjectConfig from static object to proper Gradle plugin
- Add version type support (beta/rc) to version.properties
- Clean up legacy fastlane changelogs
- Update release script to support version types
- Remove automatic fastlane changelog generation from release script
- Add BuildConfig field injection for version info
The navigation graph had a duplicate entry for DeviceManagerFragment.
This commit removes the duplicate and ensures the correct navigation action to DeviceProfileCreationFragment is present.
The lid state for AirPods Gen 4 was incorrectly reported as UNKNOWN when it should have been NOT_IN_CASE. This commit fixes the issue in both the ANC and non-ANC tests.
This commit replaces the direct usage of GeneralSettings for fetching identity and encryption keys with the DeviceProfilesRepo. BaseAirPodsTest is updated to reflect this change, mocking DeviceProfilesRepo instead of GeneralSettings.
This commit introduces a new card to the Overview screen that informs the user that the app is actively monitoring for devices when there are profiles configured but no devices are currently connected.
- Replace multiple StateFlows with single ProfileEditorState data class
- Store ByteArray keys as hex strings to enable proper equality comparison
- Fix race conditions in state initialization by setting initial and current state atomically
- Simplify change detection logic to simple data class comparison
The issue was caused by:
1. ByteArray types not implementing proper equals() (compared by reference)
2. Race conditions between multiple StateFlow updates
3. Complex change detection logic with timing issues
Now uses atomic state management with proper value-based equality.
- Shows hint when 2+ profiles exist explaining order determines priority
- Appears as flat list item at bottom, less intrusive than card
- Prevents dragging hint item, keeps it at bottom
- Uses book icon for informational guidance
The signal quality slider in `device_profile_creation_fragment.xml` now ranges from 0 to 100 with a step size of 1, previously 10 to 100 with a step size of 5.
This commit introduces a new device profile system, moving away from a single "main device" configuration in `GeneralSettings`.
Key changes:
- `DeviceProfilesRepo` now manages a list of `DeviceProfile` objects, allowing for multiple device configurations.
- On first launch with this update, existing "main device" settings from `GeneralSettings` (address, model, keys, signal quality) are migrated into a new default `AppleDeviceProfile`.
- The `MonitorWorker`, `PopUpReaction`, `AutoConnect`, and `PodHistoryRepo` have been updated to use the new `DeviceProfilesRepo` instead of the old `GeneralSettings` for device-specific information.
- `AppleFactory` now uses `DeviceProfilesRepo` to find matching profiles based on IRK.
- `TroubleShooterFragmentVM` now interacts with `DeviceProfilesRepo` for profile management during troubleshooting.
- The `create` method in `ApplePodsFactory` and its implementations are now `suspend` functions to allow for asynchronous operations like fetching profiles from the repository.
- Old "main device" preference keys in `GeneralSettings` have been renamed with an "old" prefix and will be removed in a future update.
- A new `currentProfiles()` extension function provides a convenient way to get the current list of profiles.
This commit modifies the `AppleFactory` to correctly handle `PodDevice.Model.UNKNOWN`.
Previously, if a device's model was `UNKNOWN`, it wouldn't match any profile and `isIRKMatch` would be false. This change ensures that `isIRKMatch` reflects the actual IRK match status, regardless of whether a specific profile is found.
Devices with an `UNKNOWN` model can now match profiles that are also marked as `UNKNOWN`, allowing for generic profile matching when the specific model isn't identified.
This commit enables the automatic generation of per-app language preferences by configuring the Android Gradle Plugin.
A `resources.properties` file is added to specify `en` as the `unqualifiedResLocale`, which serves as the default/fallback locale.
Additionally, `.kotlin` is added to `.gitignore` to exclude Kotlin build-related files.
Removed the deviceModel property from ApplePodsFactory interface and all 25 implementing classes across AirPods, Beats, and misc device factories. This simplifies the factory pattern as the model information can be derived from the concrete implementation type itself.
This commit adds a TODO comment to `GeneralSettings.kt` to migrate settings related to signal quality and main device details to the new device profiles system.
- Fix navigation bar overlap issues in profile creation and list screens
- Add proper edge-to-edge handling with dynamic padding for navigation bars
- Improve paired device selection with "None" option and clear functionality
- Add localized error messages for key validation with proper placeholders
- Centralize default signal quality value in DeviceProfile companion object
- Add unsaved changes detection and confirmation dialogs
- Enhance drag handle touch target size with FrameLayout wrapper
- Restore device address in profile editing and improve change tracking
- Localize all user-facing strings following project guidelines
This commit renames the `devices` package and its contents to `profiles` for better clarity and consistency. This includes renaming classes, files, and updating import statements and navigation graph references.