Introduce unified notification support and use foreground notifications for core test tasks. Added NotificationChannelType enum and NotificationHelper (cached NotificationManager and Builder cache, channel creation, notify/update/startForeground/stopForeground/cancel). Updated AndroidManifest to mark CoreTestService as a specialUse foreground service. Renamed AppConfig message constants (MSG_MEASURE_CONFIG_START, MSG_MEASURE_CONFIG_CANCEL, MSG_MEASURE_CONFIG_SUCCESS) and updated usages: MessageUtil now starts a foreground service on O+ for measurement start and handles cancel without forcing start; CoreTestService starts foreground immediately, logs lifecycle, manages RealPingWorkerService via onProgress/onFinish callbacks, and stops foreground when done; RealPingWorkerService reports progress via onProgress instead of direct UI messages; SubscriptionUpdater now uses NotificationHelper and NotificationChannelType for update notifications. These changes improve notification performance, ensure startForegroundService compliance on Android O+, and centralize notification logic.
Introduce a configurable concurrency for real-ping (true delay) tests. Add PREF_REAL_PING_CONCURRENCY and DEFAULT_REAL_PING_CONCURRENCY in AppConfig, a getter SettingsManager.getRealPingConcurrency() (parses stored value, defaults to 16, clamps to 1..128), and use that value to create the RealPingWorkerService thread pool instead of cpu * 4. Expose the setting in preferences (EditTextPreference) and add localized title strings across multiple resource files. This lets users control how many concurrent real-ping workers run.
* Update Chinese strings for UI and settings
* Refine summary for auto-remove invalid config
* Refine summaries for auto-remove and auto-sort preferences
* Change UI color setting label to '深色模式'
Introduce a new Proxy Chain server type and full support across UI and core logic. Added EConfigType.PROXYCHAIN and ProfileItem.proxyChainProfiles, new ServerProxyChainActivity, ServerProxyChainMemberAdapter, layouts and menu entries, and localized strings. CoreConfigContextBuilder now resolves proxy-chain members (from explicit list or subscription group) with robust filtering and error logging; CoreConfigManager validates chain length and logs warnings. CoreOutboundBuilder and CoreServiceManager were updated to treat PROXYCHAIN as a non-directly-runnable config type. Various UI flows (GroupServerFragment, MainActivity, ServerActivity) updated to handle the new type.
Pre-resolve outbound profiles referenced by routing rules and pass them through the runtime context so they can be injected into generated V2ray configs.
Key changes:
- Added customOutboundProfiles: Map<String, ProfileItem> to CoreConfigContext.
- CoreConfigContextBuilder: new resolveCustomOutbounds() to collect non-builtin outbound tags from routing rulesets and build the map; builder now populates customOutboundProfiles and simplifies resolvedProfiles/type handling.
- CoreConfigManager: refactored many APIs to accept CoreConfigContext instead of raw Context/guid (toConfigResult, initV2rayConfig, getRouting, getOutbounds, getBalance, etc.), and uses the pre-resolved customOutboundProfiles when injecting custom outbounds.
- injectCustomOutbounds now accepts the pre-resolved map and converts ProfileItem -> Outbound only for missing tags.
- Added logging/error handling and minor tidying to avoid repeated lookups and ensure custom outbounds are available before routing is applied.
Rationale: ensure outbounds referenced by rulesets are available early in the build pipeline, reduce duplicate lookups, and centralize runtime data in CoreConfigContext.
Add CoreConfigContext DTO and CoreResolvedType enum, and implement CoreConfigContextBuilder to centralize profile resolution (CUSTOM, POLICYGROUP, PROXYCHAIN/NORMAL) with policy-group filters and proxy-chain ordering (next -> current -> prev).
Refactor CoreConfigManager to consume CoreConfigContext: replace prior branching with buildGroupConfig, buildProxyChainConfig and buildNormalConfig, unify CUSTOM handling, add postProcessForSpeedtest and toConfigResult helpers, and remove the old getMoreOutbounds logic. Adjust outbound assembly, DNS/route handling and speedtest post-processing accordingly.
Minor cleanup: centralize outbound conversion comments in CoreOutboundBuilder and tidy several condition checks and log lines. Overall this extracts resolution logic, reduces duplication and clarifies the runtime build flow.
Extract updateOutboundWithGlobalSettings from CoreConfigManager into CoreOutboundBuilder and apply it during outbound conversion. CoreConfigManager no longer calls the function (and its NetworkType import was removed); CoreOutboundBuilder.convert now runs the global-settings update and returns null if the update fails. This centralizes outbound/global preference handling and eliminates duplicated update logic across the codebase.
Refactor: rename handler package/classes and services from V2Ray*/V2ray* to Core*/Core (e.g. V2rayConfigManager -> CoreConfigManager, V2RayNativeManager -> CoreNativeManager, V2RayServiceManager -> CoreServiceManager, and service classes V2RayVpnService/V2RayProxyOnlyService/V2RayTestService -> CoreVpnService/CoreProxyOnlyService/CoreTestService). Update AndroidManifest service entries and all imports/usages across the app (notifications, receivers, widgets, UI, services, workers) to reference the renamed classes and package (com.v2ray.ang.core). Comments and references were adjusted to match the new names; no functional logic changes intended.
Introduce CoreOutboundBuilder.kt to centralize ProfileItem → OutboundBean conversion logic. Provides createInitOutbound and per-protocol builders for VMESS, VLESS, Shadowsocks, SOCKS, Trojan, WireGuard, Hysteria2 and HTTP. Includes reusable helpers populateTransportSettings and populateTlsSettings to configure network transport, TLS/REALITY settings, finalmask manipulation and optional fragmentation via MMKV prefs. Also adds domain resolution logic (with IPv6 preference) in getServerAddress and preserves original format-specific behaviors.
Wrap startRealPing(guid) in a catch(Throwable) that ignores errors so exceptions during measurement won't propagate. This ensures the finally block always runs to decrement totalCount and runningCount, preventing the worker from being interrupted by unexpected errors.
* Initial plan
* Refactor subscription auto-update system into SubscriptionUpdater facade
Agent-Logs-Url: https://github.com/2dust/v2rayNG/sessions/63125c89-4db9-4572-8adb-10c29ea531f5
Co-authored-by: 2dust <31833384+2dust@users.noreply.github.com>
* Add TODO comment to legacy fallback in SubscriptionUpdater
Agent-Logs-Url: https://github.com/2dust/v2rayNG/sessions/63125c89-4db9-4572-8adb-10c29ea531f5
Co-authored-by: 2dust <31833384+2dust@users.noreply.github.com>
* Use per-subscription auto-update intervals
Migrate subscription auto-update from a global toggle/interval to per-subscription scheduling.
- Add per-subscription updateInterval (Long, default 1440 minutes) and persist in SubEdit UI; validate minimum interval (15 minutes).
- Update SubscriptionUpdater to schedule/cancel tasks per subscription, compute initial delay from subscription.lastUpdated, and skip when autoUpdate is disabled or subId is missing.
- Remove legacy global auto-update prefs and fallback logic: deleted global prefs/UI handling, MmkvManager last-attempt encode/decode, and related default setting.
- Ensure cancelling of scheduled task when removing a subscription and adjust SettingsManager initialization.
- Add localized toast strings for invalid update interval and update related layouts/resources.
This change enables individual update intervals per subscription and simplifies the updater by removing legacy global state and last-attempt persistence.
* Allow optional force-reschedule for subscriptions
Add a forceReschedule flag to SubscriptionUpdater.sync to choose the WorkManager policy (KEEP by default, REPLACE when forced). Refactor scheduleOne to accept an ExistingPeriodicWorkPolicy and use it when enqueuing periodic work; syncOne now forces REPLACE so a manual refresh recalculates next run. Remove the cancelAll helper and improve logging to include the reschedule flag/policy. This lets startup keep existing periodic work while allowing explicit reschedules when needed (e.g., after manual updates).
---------
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: 2dust <31833384+2dust@users.noreply.github.com>
Remove echForceQuery support across the app: delete the echForceQuery fields from ProfileItem and V2rayConfig, stop mapping it in V2rayConfigManager, and remove the related UI spinner and containers in ServerActivity and layout_tls.xml. Also delete the ech_force_query_value array and all localized string entries for the ECH force query label, and adjust focus navigation to skip the removed control. This cleans up a deprecated/unused ECH force query setting.
Bump AGP to 9.2.0 in gradle/libs.versions.toml and update Gradle wrapper distribution to gradle-9.4.1 in gradle/wrapper/gradle-wrapper.properties. Keeps the build tooling up to date to take advantage of Gradle/AGP fixes and improvements.
Co-Authored-By: Copilot <198982749+Copilot@users.noreply.github.com>
* Add MTU and TTI settings in KCP network
* Rename ProfileItem.tti to kcpTti
Rename the ProfileItem field `tti` to `kcpTti` and update all usages accordingly. Changes update parsing/serialization in FmtBase (map query param "tti" to config.kcpTti and emit it), KCP stream settings mapping in V2rayConfigManager, UI bindings in ServerActivity, and equality checks in ProfileItem to use kcpTti. This clarifies that the field applies to KCP-specific TTI values while preserving the external query key.
Co-Authored-By: Copilot <198982749+Copilot@users.noreply.github.com>
* Add kcpMtu/kcpTti for KCP transport
Introduce kcpMtu and kcpTti properties on ProfileItem and update equality checks. Parse and emit KCP-specific mtu/tti in FmtBase (use kcpMtu/kcpTti instead of the generic mtu). Wire kcpMtu into V2rayConfigManager when building KCP stream settings and update ServerActivity to read/write the UI field to profileItem.kcpMtu/kcpTti. This separates KCP MTU/TTI from the general mtu field and removes a duplicated kcpTti entry.
Co-Authored-By: Copilot <198982749+Copilot@users.noreply.github.com>
---------
Co-authored-by: 2dust <31833384+2dust@users.noreply.github.com>
Co-authored-by: Copilot <198982749+Copilot@users.noreply.github.com>
Replace HttpURLConnection-based networking with OkHttp and add proxy username/password support. Introduces buildOkHttpClient, updated getUrlContent/getUrlContentWithUserAgent signatures, and downloadToFile; callers in AngConfigManager, SpeedtestManager, UpdateCheckerManager, PerAppProxyActivity, UserAssetActivity and UserAssetViewModel now pass SOCKS proxy credentials. Removes createProxyConnection and related URL-resolve logic, clears HTTP inbound auth/udp in V2rayConfigManager, and simplifies SettingsManager port generation. These changes enable authenticated proxy requests, improved redirect handling and more robust file downloads.
* Handle unidentified package UID resolution
Add special handling for unidentified package names.
* Add method to create special unidentified app item
Added a method to create a special unidentified app item for the app picker.
* Support unidentified app UID and label
---------
Co-authored-by: 2dust <31833384+2dust@users.noreply.github.com>
Introduce an AppPickerActivity to browse and select installed apps (with search, select-all and invert selection). Add AppSelectorAdapter, activity_app_picker layout and menu_app_picker menu, and register the activity in AndroidManifest.xml. Integrate the picker into RoutingEditActivity using an ActivityResult launcher and add a btn_process_picker to the routing edit layout; selected package list is loaded into the process EditText. Minor UI adjustments include padding for the EditText and marking system apps in the list.
Allow routing rules to reference outbounds by server remarks and inject missing outbounds into the generated V2ray config. Adds BUILTIN_OUTBOUND_TAGS, a pre-pass (injectCustomOutbounds) that converts referenced non-builtin tags to outbounds, and a fallback to the proxy tag when an outbound couldn't be injected. Updates getBalance to use AppConfig.TAG_PROXY constant. Replaces the outbound-tag Spinner with an AutoCompleteTextView + dropdown button that suggests builtin tags and existing profile remarks, adds a drop-down drawable and a hint string resource.
Introduce a centralized LogUtil and migrate logging calls across the app to use it. Replaced android.util.Log imports/usages in many modules (fmt, handler, helper, receiver, service, ui, util, viewmodel, tests) and added a new LogUtil.kt file. Also trigger LogUtil.refreshLogLevel() when PREF_LOGLEVEL changes in MmkvPreferenceDataStore so runtime log level updates take effect.
Introduce process field for routing rules and wire it through UI, config parsing, and runtime resolution. Adds a PackageUidResolver utility to map package names to UIDs (with caching) and converts user-entered package names into UIDs when building v2ray routing rules. Updates V2rayConfig types, RoutingEditActivity layout/bindings/strings to accept process input, and adjusts getRouting to receive Context. Also adds extra logging and a defensive check in V2RayServiceManager when resolving connection owner UID.
Introduce a dynamic SOCKS port feature: add PREF_DYNAMIC_SOCKS_PORT key, settings UI checkbox and localized strings, and pref XML entry. SettingsManager now holds a runtimeSocksPort, can generate and refresh a random port (generateRandomSocksPort, refreshRuntimeSocksPort) and respects the dynamic setting when returning getSocksPort(). V2Ray service startup triggers a runtime port refresh. Settings UI disables manual SOCKS port input when dynamic mode is enabled. Minor i18n additions (QR code/title) included for several locales.