Add telephony settings, APN provisioning support, and LineageOS APN submodule integration
- settings.xml: add conditional telephony block (mobile data, VoLTE, roaming, network mode) - res/xml/apns.xml: simple single-file APN fallback with full attribute documentation - assets/apns/global.xml: multi-file APN template compatible with LineageOS/android_vendor_apn - build.gradle: add assets srcDir, Gradle copy tasks to pull only *.xml from APN submodules
This commit is contained in:
@@ -0,0 +1,74 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
Global / carrier-agnostic APNs.
|
||||
Format is compatible with LineageOS / AOSP apns-conf.xml.
|
||||
|
||||
ConfigProvisioner walks all .xml files under assets/apns/ recursively,
|
||||
so you can organise files however you like:
|
||||
|
||||
assets/apns/global.xml ← this file
|
||||
assets/apns/north_america.xml
|
||||
assets/apns/europe.xml
|
||||
assets/apns/asia_pacific.xml
|
||||
assets/apns/north_america/us_tmobile.xml
|
||||
assets/apns/north_america/ca_rogers.xml
|
||||
…
|
||||
|
||||
Format is compatible with LineageOS/android_vendor_apn and AOSP apns-conf.xml.
|
||||
|
||||
To include LineageOS APN data, add it as a submodule at the repo ROOT
|
||||
(not inside assets/) — build.gradle copies only the *.xml files into the APK,
|
||||
leaving scripts, schemas, and license files behind:
|
||||
|
||||
git submodule add https://github.com/LineageOS/android_vendor_apn lineage_apn
|
||||
|
||||
Additional submodule sources can be added in the apnSubmodules map in build.gradle.
|
||||
|
||||
Attributes:
|
||||
carrier / name Display name ("carrier" = AOSP/pgaskin, "name" = custom — both ok)
|
||||
mcc Mobile country code (3 digits)
|
||||
mnc Mobile network code (2–3 digits, leading zero matters)
|
||||
apn APN string
|
||||
type Comma-separated: default, supl, mms, fota, ims, cbs, ia, emergency
|
||||
protocol IP | IPV6 | IPV4V6
|
||||
roaming_protocol same as protocol
|
||||
server WAP gateway server (rarely used)
|
||||
proxy HTTP proxy host
|
||||
port HTTP proxy port
|
||||
mmsc MMS centre URL (required for type=mms)
|
||||
mmsproxy MMS proxy host
|
||||
mmsport MMS proxy port
|
||||
user APN username
|
||||
password APN password
|
||||
authtype -1=none, 0=PAP, 1=CHAP, 2=PAP or CHAP
|
||||
bearer_bitmask Allowed RATs bitmask (0 = all)
|
||||
profile_id Carrier profile ID (integer, rarely needed)
|
||||
mtu MTU override in bytes (0 = default)
|
||||
modem_cognitive true | false — let modem manage APN
|
||||
max_conns Max simultaneous connections
|
||||
wait_time Retry wait time (ms)
|
||||
max_conns_time Max connection time (ms)
|
||||
carrier_enabled true | false (or 1 | 0)
|
||||
mvno_type spn | imsi | gid | iccid (for MVNO entries)
|
||||
mvno_match_data Match string for the chosen mvno_type
|
||||
|
||||
Deduplication key: numeric + apn + mvno_type + mvno_match_data.
|
||||
Two entries sharing MCC/MNC/APN but different MVNO identity are kept separately.
|
||||
-->
|
||||
<apns version="8">
|
||||
|
||||
<!-- Add real APN entries here. The example below is commented out. -->
|
||||
|
||||
<!--
|
||||
<apn carrier="Example Internet"
|
||||
mcc="000"
|
||||
mnc="00"
|
||||
apn="internet"
|
||||
type="default,supl"
|
||||
protocol="IPV4V6"
|
||||
roaming_protocol="IPV4V6"
|
||||
bearer_bitmask="0"
|
||||
carrier_enabled="true" />
|
||||
-->
|
||||
|
||||
</apns>
|
||||
@@ -19,6 +19,8 @@ android {
|
||||
main {
|
||||
manifest.srcFile 'AndroidManifest.xml'
|
||||
res.srcDirs = ['res']
|
||||
// 'assets' = hand-authored files; generated/assets = XMLs copied from submodules
|
||||
assets.srcDirs = ['assets', "$buildDir/generated/assets"]
|
||||
java.srcDirs = ['src']
|
||||
kotlin.srcDirs = ['src']
|
||||
}
|
||||
@@ -51,3 +53,42 @@ android {
|
||||
dependencies {
|
||||
implementation 'org.jetbrains.kotlin:kotlin-stdlib:2.0.21'
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// APN submodule copy tasks
|
||||
//
|
||||
// Each entry below copies only *.xml files from a repo submodule into
|
||||
// build/generated/assets/apns/<name>/ so non-XML files (scripts, schemas,
|
||||
// YAML, licenses) are never packaged into the APK.
|
||||
//
|
||||
// To add a source:
|
||||
// 1. git submodule add <url> <localDir> (at repo root, not inside assets/)
|
||||
// 2. Add a copyApns_<name> task below following the same pattern.
|
||||
//
|
||||
// To use LineageOS/android_vendor_apn:
|
||||
// git submodule add https://github.com/LineageOS/android_vendor_apn lineage_apn
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
def apnSubmodules = [
|
||||
// localDir (relative to project root) -> dest name under assets/apns/
|
||||
'lineage_apn': 'lineage',
|
||||
]
|
||||
|
||||
apnSubmodules.each { srcDir, destName ->
|
||||
def taskName = "copyApns_${destName}"
|
||||
tasks.register(taskName, Copy) {
|
||||
description = "Copy *.xml APN files from ${srcDir}/ into generated assets"
|
||||
onlyIf { file(srcDir).exists() } // no-op if submodule not initialised
|
||||
from(srcDir) { include '**/*.xml' }
|
||||
into "$buildDir/generated/assets/apns/${destName}"
|
||||
}
|
||||
}
|
||||
|
||||
// Hook every copy task before the corresponding merge*Assets task
|
||||
tasks.configureEach { task ->
|
||||
if (task.name.startsWith('merge') && task.name.endsWith('Assets')) {
|
||||
apnSubmodules.each { srcDir, destName ->
|
||||
task.dependsOn("copyApns_${destName}")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,93 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
Fallback APN definitions (simple / single-file mode).
|
||||
|
||||
If assets/apns/ contains any .xml files, ConfigProvisioner uses those
|
||||
instead and ignores this file entirely. Use assets/apns/ for multi-file
|
||||
region/carrier organisation (compatible with LineageOS apns-conf.xml format).
|
||||
|
||||
This file is only read when assets/apns/ is absent or empty.
|
||||
|
||||
Existing APNs with the same numeric+apn pair are skipped (no duplicates).
|
||||
|
||||
Required attributes:
|
||||
name Display name shown in APN settings
|
||||
numeric MCCMNC string, e.g. "310260" (T-Mobile US)
|
||||
mcc Mobile country code (3 digits)
|
||||
mnc Mobile network code (2–3 digits)
|
||||
apn APN string, e.g. "internet"
|
||||
|
||||
Optional attributes:
|
||||
type Comma-separated: default, supl, mms, fota, ims, cbs, ia, emergency
|
||||
Omit for "default,supl" (internet + location)
|
||||
protocol IP | IPV6 | IPV4V6 (default: IPV4V6)
|
||||
roaming_protocol same as protocol (default: IPV4V6)
|
||||
mmsc MMS centre URL (required for MMS type)
|
||||
mmsproxy MMS proxy host
|
||||
mmsport MMS proxy port
|
||||
user APN username (if required by carrier)
|
||||
password APN password (if required by carrier)
|
||||
carrier_enabled 1 | 0 (default: 1)
|
||||
bearer comma-separated RATs: LTE,HSPA,UMTS,EDGE,GPRS,EHRPD,EVDO_B,…
|
||||
Omit to allow all bearers.
|
||||
|
||||
Example — Generic internet APN (replace mcc/mnc/apn with real values):
|
||||
|
||||
<apn
|
||||
name="My Carrier Internet"
|
||||
numeric="00000"
|
||||
mcc="000"
|
||||
mnc="00"
|
||||
apn="internet"
|
||||
type="default,supl"
|
||||
protocol="IPV4V6"
|
||||
roaming_protocol="IPV4V6"
|
||||
carrier_enabled="1" />
|
||||
|
||||
Example — MMS APN:
|
||||
|
||||
<apn
|
||||
name="My Carrier MMS"
|
||||
numeric="00000"
|
||||
mcc="000"
|
||||
mnc="00"
|
||||
apn="mms"
|
||||
type="mms"
|
||||
mmsc="http://mmsc.example.com"
|
||||
mmsproxy="192.168.1.1"
|
||||
mmsport="8080"
|
||||
protocol="IPV4V6"
|
||||
roaming_protocol="IPV4V6"
|
||||
carrier_enabled="1" />
|
||||
|
||||
Example — IMS (VoLTE) APN:
|
||||
|
||||
<apn
|
||||
name="My Carrier IMS"
|
||||
numeric="00000"
|
||||
mcc="000"
|
||||
mnc="00"
|
||||
apn="ims"
|
||||
type="ims"
|
||||
protocol="IPV4V6"
|
||||
roaming_protocol="IPV4V6"
|
||||
carrier_enabled="1" />
|
||||
-->
|
||||
<apns>
|
||||
|
||||
<!-- Add real APN entries here. All examples are commented out. -->
|
||||
|
||||
<!--
|
||||
<apn
|
||||
name="Example Internet"
|
||||
numeric="00000"
|
||||
mcc="000"
|
||||
mnc="00"
|
||||
apn="internet"
|
||||
type="default,supl"
|
||||
protocol="IPV4V6"
|
||||
roaming_protocol="IPV4V6"
|
||||
carrier_enabled="1" />
|
||||
-->
|
||||
|
||||
</apns>
|
||||
@@ -89,4 +89,40 @@
|
||||
</if>
|
||||
-->
|
||||
|
||||
<!-- ===== Telephony ===== -->
|
||||
<!-- Applied only when device has telephony hardware (SIM slot) -->
|
||||
<if feature="android.hardware.telephony">
|
||||
<!-- Mobile data on by default -->
|
||||
<global name="mobile_data" value="1" />
|
||||
<!-- Data roaming off by default — safe default, user can enable -->
|
||||
<global name="data_roaming" value="0" />
|
||||
<!--
|
||||
Preferred network mode:
|
||||
9 = LTE/WCDMA/GSM auto (most common)
|
||||
22 = LTE/WCDMA/GSM/CDMA auto
|
||||
-->
|
||||
<global name="preferred_network_mode" value="9" />
|
||||
<!-- VoLTE / enhanced 4G IMS mode on -->
|
||||
<global name="enhanced_4g_mode_enabled" value="1" />
|
||||
<!-- WiFi calling off by default — carrier may require activation -->
|
||||
<global name="wfc_ims_enabled" value="0" />
|
||||
<!-- WiFi calling mode: 0=WiFi only, 1=prefer cellular, 2=prefer WiFi -->
|
||||
<global name="wfc_ims_mode" value="2" />
|
||||
<!-- VT (video calling over IMS) on -->
|
||||
<global name="vt_ims_enabled" value="1" />
|
||||
<!-- Captive portal detection — 1=prompt, 2=avoid, 0=off -->
|
||||
<global name="captive_portal_mode" value="1" />
|
||||
</if>
|
||||
|
||||
<!-- GSM/LTE networks only -->
|
||||
<if feature="android.hardware.telephony.gsm">
|
||||
<!-- Force IPv4v6 dual stack by default (modern networks) -->
|
||||
<!-- ConfigProvisioner handles APN insertion separately via apns.xml -->
|
||||
</if>
|
||||
|
||||
<!-- Devices with IMS/VoLTE hardware support -->
|
||||
<if feature="android.hardware.telephony.ims">
|
||||
<global name="enhanced_4g_mode_enabled" value="1" />
|
||||
</if>
|
||||
|
||||
</settings>
|
||||
|
||||
Reference in New Issue
Block a user