Skip to content

Add app cleaner feature#1351

Merged
lihenggui merged 37 commits into
mainfrom
feature/share-menu-query
Nov 3, 2025
Merged

Add app cleaner feature#1351
lihenggui merged 37 commits into
mainfrom
feature/share-menu-query

Conversation

@lihenggui

Copy link
Copy Markdown
Owner

This pull request introduces a new "Share Filter" feature to the app, integrating it into navigation, top-level destinations, and supporting localization. It also adds the necessary data layer and Android manifest queries to support the feature, along with new test dependencies.

Feature Integration

  • Added feature.sharefilter module to app dependencies, enabling the new feature in the app build.
  • Integrated the Share Filter screen into navigation (BlockerNavHost.kt), allowing users to access it from the app. [1] [2]
  • Added SHARE_FILTER as a new top-level destination, including icon and route configuration. [1] [2] [3] [4]

Localization

Data Layer and Permissions

  • Added new data sources for Share Target activities: CacheShareTargetDataSource and LocalShareTargetDataSource, implementing logic to query and represent share target activities. [1] [2]
  • Updated DataModule.kt to bind the new ShareTargetRepository and its local implementation. [1] [2]
  • Updated Android manifest to include intent queries for share actions (SEND, SEND_MULTIPLE), enabling the app to discover share targets.

Testing

  • Added turbine library to test dependencies in core/data for improved coroutine flow testing.

lihenggui and others added 10 commits October 31, 2025 11:38
Change-Id: I38a938b533761da7e539b155aa32f6036a845374
Change-Id: I789c6bbdd25615b5b3998ffe95c03ebfd83ad710
Change-Id: I68d8d725b95d2e715dafaf9fc5bcf3df37811b41
Change-Id: If91cd85537dfd54b8d72e973407f0f50bc2f7a0a
Change-Id: I3836f2233ee53343f5ba2d48a14e34a54e3f5928
Change-Id: I93a059dba79c76be451a649bf18b94a0b9c0259d
- Add core_designsystem_ic_share_off.xml drawable resource
- Add ShareOff icon reference to BlockerIcons
- Update TopLevelDestination to use Icon sealed class
- Update BlockerApp to render both ImageVectorIcon and DrawableResourceIcon types
- Apply ShareOff icon to Share Filter navigation item
- Remove internal modifier from LocalShareTargetRepository to make it accessible for Hilt injection
- Fix ShareTargetActivityDaoTest to use correct ShareTargetDatabase instead of non-existent BlockerDatabase
@lihenggui lihenggui force-pushed the feature/share-menu-query branch from 7ab7cda to a205319 Compare November 2, 2025 03:28
lihenggui and others added 19 commits November 2, 2025 08:10
Replace PackageManager.queryIntentActivities() with ApkParser.getActivitiesWithIntentFilters() in LocalShareTargetDataSource for more comprehensive manifest parsing. This enables direct detection of activities with VIEW, SEND, SEND_MULTIPLE actions and BROWSABLE category.

Changes:
- Update ApkParser to include ACTION_SEND_MULTIPLE filtering
- Add resource label resolution using PackageManager.getResourcesForApplication()
- Change ApkParser visibility to public for cross-module access
- Add test coverage for SEND_MULTIPLE action filtering
- Fix test field reference from .name to .componentName
- Move DAO interactions from Repository to CacheShareTargetDataSource
- Add updateActivities method to CacheShareTargetDataSource
- Simplify resolveActivityLabel to use PackageManager.getActivityInfo directly
- Update tests to verify interactions with DataSource instead of DAO

This improves architectural layering by ensuring Repository only interacts
with DataSources, not DAOs directly.
- Add @serializable annotations to ActivityIntentFilterInfo, IntentFilterInfo, and IntentFilterDataInfo
- Create IntentFilterInfoConverter for JSON serialization/deserialization
- Add intentFilters and label fields to ShareTargetActivityEntity
- Update ShareTargetDatabase schema version from 1 to 2
- Add kotlinx.serialization support to core:common module
- Add core:common dependency to core:database module
- Populate intent filter data from ApkParser in LocalShareTargetDataSource
- Update tests to include new entity fields

This enables caching complete intent filter information (actions, categories, data specs)
for share target activities, which can be used for categorization and filtering in the UI.
- Move ActivityIntentFilterInfo, IntentFilterInfo, and IntentFilterDataInfo from core:common/utils to core:model/data
- Split into separate files (one class per file) for better organization
- Add @ColumnInfo annotations to label and intentFilters fields in ShareTargetActivityEntity
- Update all import statements across affected modules
- Remove core:common dependency from core:database
- Add core:model dependency to core:common for ApkParser usage
- Update copyright headers to 2025 for new files

This improves module architecture by placing data models in the appropriate layer
and ensures proper column naming in the database schema.
Change core:model dependency in core:common from api to implementation.
This reduces unnecessary transitive dependencies while maintaining functionality,
as core:data (the only consumer of ApkParser) already has core:model access
through core:database.
Implement logic to identify share target activities that meet specific
intent filter criteria (ACTION_SEND/SEND_MULTIPLE with DEFAULT category
and mimeType). Display AssistChip with '分享控件' label for qualifying
components in the share filter UI.

- Create ShareTargetUiItem wrapper with isShareableComponent flag
- Update ViewModel to compute shareable component status
- Add AssistChip display in ShareTargetItem composable
- Update all related UI components and extension functions
- Add string resources in English, Simplified and Traditional Chinese
Simplify chip text to just 'Share' (or equivalent) across all supported
languages for better display in compact UI. Updated translations:

- English: Share
- Arabic: مشاركة
- Spanish: Compartir
- French: Partager
- Indonesian: Berbagi
- Portuguese: Partilhar
- Brazilian Portuguese: Compartilhar
- Russian: Поделиться
- Turkish: Paylaş
- Simplified Chinese: 分享
- Traditional Chinese: 分享
- Change mutable list references from var to val in ApkParser
- Handle abbreviated activity names starting with '.' by prepending package name
- Add missing ComponentName import to LocalShareTargetDataSource
Implement detection for three activity launch types:
- Explicit launch (exported=true)
- Launcher entry (MAIN + LAUNCHER intent filter)
- Deeplink entry (VIEW + BROWSABLE + data)

Update UI to display multiple chips using FlowRow:
- Chips shown in detection order
- Launcher entry highlighted with error color
- Support for multiple simultaneous chips per activity

Add multi-language string resources for all five supported languages.
Add FakeShareTargetRepository and bind it in TestDataModule to fix
unit test compilation errors. The ShareTargetRepository was missing
from the test dependency injection configuration, causing Hilt to
fail when generating test components.

Changes:
- Create FakeShareTargetRepository in core:data-test
- Add ShareTargetRepository binding in TestDataModule
- Fix Dagger/MissingBinding error in unit tests
Fix test to account for the new SHARE_FILTER top-level destination.
The test was expecting 3 destinations but there are now 4: APP, RULE,
SHARE_FILTER, and SEARCH.
Update screenshot test to use HiltComponentActivity and @HiltAndroidTest
to properly support Hilt dependency injection for ShareFilterViewModel.

Changes:
- Add @HiltAndroidTest annotation
- Use HiltComponentActivity instead of ComponentActivity
- Add HiltAndroidRule for proper Hilt setup
- Add ui-test-hilt-manifest test dependency
- Call hiltRule.inject() in setup method
- Changed ShareFilterScreenContent from private to internal for test access
- Rewrote screenshot tests to use ShareFilterScreenContent directly instead of ShareFilterScreen
- Removed HiltAndroidTest setup to avoid ViewModel initialization in screenshot tests
- Removed ui-test-hilt-manifest test dependency as it's no longer needed
- Added tests for both Loading and Success states
- Follows the same pattern as LicensesScreenScreenshotTest

This fixes the issue where screenshot tests would hang because ShareFilterScreen
uses hiltViewModel() which starts an infinite Flow collection in the init block.
Screenshot tests should only test UI rendering, not business logic.
Add ref parameter to checkout steps to avoid detached HEAD state
when running in pull_request context. This allows git-auto-commit-action
to properly commit and push changes (screenshots, dependency baselines, etc.)
back to the PR branch.
lihenggui and others added 4 commits November 2, 2025 17:45
…urification_title

- Update English translation from 'Share Filter' to 'App Purification'
- Update Chinese translation from '分享净化' to '应用净化'
- Update all language translations across 11 languages
- Update reference in TopLevelDestination.kt
- Fix French translation apostrophe escaping

Screenshot tests will be updated by CI
Rename string resource ID from 'feature_apppurification_title' to
'feature_sharefilter_apppurification_title' to comply with module's
resource prefix requirement.

The feature/sharefilter module requires all resources to be prefixed
with 'feature_sharefilter_'. The app-compose module keeps the
'feature_apppurification_title' ID as it has no prefix requirement.

This resolves lint errors:
- ResourceName: Resource must start with module prefix

Changes:
- Updated all 11 language string files in feature/sharefilter
- Maintained same translation content ("应用净化" / "App Purification")
- No code changes needed (TopLevelDestination references app-compose version)
Comment thread feature/sharefilter/src/main/res/values/strings.xml Fixed
Comment thread feature/sharefilter/src/main/res/values/strings.xml Fixed
Comment thread feature/sharefilter/src/main/res/values/strings.xml Fixed
Comment thread feature/sharefilter/src/main/res/values/strings.xml Fixed
@lihenggui lihenggui changed the title Add share cleaner feature Add app cleaner feature Nov 3, 2025
- Remove unused string resource 'feature_sharefilter_apppurification_title' from all translation files
- Add missing translations for 'explicit_launch', 'launcher_entry', 'deeplink_entry' in ar, es, fr, in, pt languages
- Complete ShareFilterViewModelTest with comprehensive unit tests following given_when_then naming convention

Change-Id: I7ef1d5162d5cf41cae31794abf1377413ee576ac
- Add mockito-kotlin and core.dataTest dependencies
- Fix ShareTargetRepository mock implementation
- Fix PackageInfo applicationInfo property mocking
- Remove non-existent setControlComponentResult method calls

Note: Some tests still failing, needs further investigation
Change-Id: I3941f14272a3ccf7d894ff2b601976a7d39bd24c
- Update all tests to skip initial empty state from MutableStateFlow
- Fix permission test by creating new ViewModel instance after permission change
- Simplify search test using testScheduler.advanceUntilIdle()
- All 17 tests now passing

Change-Id: If5b9bbdf394cd29fe8e86e5d6c7ca05058e42006
Change-Id: I47880c7427ca267b570f59e91d119e61d91ff8a2
@lihenggui lihenggui merged commit 7a4484e into main Nov 3, 2025
4 checks passed
@lihenggui lihenggui deleted the feature/share-menu-query branch November 3, 2025 22:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants