Compare commits

...

10 Commits

Author SHA1 Message Date
Michael Bestas
3c7aad41aa
motorola: Abuse symlinks to generate fsg mount point
Change-Id: Ifed99fe5a0e8e520fd792c53550f6f8ba8007f67
2025-01-13 14:46:52 +02:00
Aaron Kling
e144809011 interfaces: hash current interfaces
Change-Id: Ia27b7c5ff9ed4004807887e204f889fe3575dff2
2024-08-18 17:10:29 -05:00
dianlujitao
946de82195 MotoNrEnabler: fix null check of getSystemService after U QPR2
Change-Id: Iec4852986457495ca15c94d9f7e425c999f85a60
2024-03-21 20:08:10 +08:00
Michael Bestas
3dc348ff37
MotoActions: Convert to SwitchPreferenceCompat
Change-Id: Ic1cbaba37d499da1855af9c3930f2df426e2d3af
2024-03-10 22:46:10 +02:00
Peter Kalauskas
320254d1c4
MotoActions: Enable use_resource_processor for all sysui deps
This will make the build faster

Test: m checkbuild
Bug: 295208392
Change-Id: I0c1bd901429bbe3bf81c1530e156735f8637a96e
2024-03-10 22:46:04 +02:00
Michael Bestas
9c6227b575
MotoActions: Update DozePreferenceFragment for QPR2
The OnMainSwitchChangeListener is replaced with OnCheckedChangeListener

Change-Id: I6b8cb85210eac5f0499a08a8392b3f6997542f86
2024-03-10 22:45:57 +02:00
dianlujitao
42a4d5f209 MotoNrEnabler: Add a service to enable 5G via OEM RIL request
Clearing and rebuilding modem cache (e.g. mdmddr, mdm1m9kefs1,
mdm1m9kefs2, carrier, and ddr partitions for MDM devices) is typically
necessary after modem firmware upgrade. However, NR is disabled in
Moto's modem firmware by default, so choosing NR results in "No signal"
after rebuilding modem cache with custom ROMs installed. Users have to
go back to stock once to make it work again, which is a huge pain.

It's observed that stock ROMs control NR via a custom RIL request, and
choose it based on carrier config and user preference (yes they have a
toggle in system settings) after SIM provisioning. Here, we implement a
service to automatically enable NR and DSS in the same approach, so
that users no longer need to go back to stock after upgrading modem
firmware. The implementation is based on telephony-common.jar,
qti-telephony-common.jar and qcom-moto-telephony-ext.jar from nio.
You're suggested to check if the magic numbers and payload formats
match your device's stock ROM before using this service.

Change-Id: I5ecfae93717fe87e6b1c1a75caa674b466403391
2024-01-12 23:22:35 +08:00
SGCMarkus
0847f2dbca interfaces: add com.motorola.hardware.biometric.fingerprint@1.0
Change-Id: I85cd687bf059eac111829705f26ee288eb5fa663
2023-01-29 06:22:58 +01:00
hpnightowl
126240e564 MotoActions: Don't hardcode fillColor value of drawables
* White stroke color  makes it very hard to interpret icons in dark mode
   Before/After: https://imgur.com/a/1vz6SON

Change-Id: Idaedaa4bb62a42253c1000001476ccfedd01b790
2023-01-08 17:42:24 +00:00
Bruno Martins
ed49bbc414 MotoActions: Fix compilation for QPR1 merge
Change-Id: Ifa602ed1ae0734dbda40663770f2e54075bfa208
2022-12-06 14:09:25 -05:00
30 changed files with 895 additions and 41 deletions

11
Android.bp Normal file
View File

@ -0,0 +1,11 @@
//
// Copyright (C) 2025 The LineageOS Project
// SPDX-License-Identifier: Apache-2.0
//
install_symlink {
name: "vendor_fsg_mountpoint",
vendor: true,
installed_location: "fsg/.keep",
symlink_target: "/dev/null",
}

View File

@ -4,5 +4,5 @@
android:tint="?android:attr/colorControlNormal"
android:viewportWidth="24"
android:viewportHeight="24">
<path android:fillColor="#000" android:pathData="M6.58,19H14.58V22H6.58V19M19.74,11.6C19.55,11.4 19.29,11.28 19,11.28L18.78,11.31L15.58,13V11.83L16.09,2.9C16.12,2.35 15.7,1.87 15.15,1.84C14.6,1.81 14.12,2.23 14.09,2.78L13.82,7.47H13.58L12.54,7.58V2A1,1 0 0,0 11.54,1C11,1 10.54,1.45 10.54,2V8.41L9.72,8.78L9.03,3.32C8.96,2.77 8.46,2.38 7.91,2.45C7.36,2.5 6.97,3 7.04,3.57L7.81,9.63L7.43,9.8C7.3,9.85 7.18,9.93 7.07,10L5.97,6.11C5.81,5.54 5.25,5.2 4.71,5.34C4.18,5.5 3.88,6.08 4.04,6.65L6.61,15.77C6.61,15.8 6.63,15.84 6.64,15.87L6.67,16H6.68C6.9,16.57 7.47,17 8.08,17H14.58C14.97,17 15.32,16.84 15.58,16.57L20.5,12.37L19.74,11.6Z" />
<path android:fillColor="?android:attr/colorPrimary" android:pathData="M6.58,19H14.58V22H6.58V19M19.74,11.6C19.55,11.4 19.29,11.28 19,11.28L18.78,11.31L15.58,13V11.83L16.09,2.9C16.12,2.35 15.7,1.87 15.15,1.84C14.6,1.81 14.12,2.23 14.09,2.78L13.82,7.47H13.58L12.54,7.58V2A1,1 0 0,0 11.54,1C11,1 10.54,1.45 10.54,2V8.41L9.72,8.78L9.03,3.32C8.96,2.77 8.46,2.38 7.91,2.45C7.36,2.5 6.97,3 7.04,3.57L7.81,9.63L7.43,9.8C7.3,9.85 7.18,9.93 7.07,10L5.97,6.11C5.81,5.54 5.25,5.2 4.71,5.34C4.18,5.5 3.88,6.08 4.04,6.65L6.61,15.77C6.61,15.8 6.63,15.84 6.64,15.87L6.67,16H6.68C6.9,16.57 7.47,17 8.08,17H14.58C14.97,17 15.32,16.84 15.58,16.57L20.5,12.37L19.74,11.6Z" />
</vector>

View File

@ -4,5 +4,5 @@
android:tint="?android:attr/colorControlNormal"
android:viewportWidth="24"
android:viewportHeight="24">
<path android:fillColor="#000" android:pathData="M9.64,13.4C8.63,12.5 7.34,12.03 6,12V15L2,11L6,7V10C7.67,10 9.3,10.57 10.63,11.59C10.22,12.15 9.89,12.76 9.64,13.4M18,15V12C17.5,12 13.5,12.16 13.05,16.2C14.61,16.75 15.43,18.47 14.88,20.03C14.33,21.59 12.61,22.41 11.05,21.86C9.5,21.3 8.67,19.59 9.22,18.03C9.5,17.17 10.2,16.5 11.05,16.2C11.34,12.61 14.4,9.88 18,10V7L22,11L18,15M13,19A1,1 0 0,0 12,18A1,1 0 0,0 11,19A1,1 0 0,0 12,20A1,1 0 0,0 13,19M11,11.12C11.58,10.46 12.25,9.89 13,9.43V5H16L12,1L8,5H11V11.12Z" />
<path android:fillColor="?android:attr/colorPrimary" android:pathData="M9.64,13.4C8.63,12.5 7.34,12.03 6,12V15L2,11L6,7V10C7.67,10 9.3,10.57 10.63,11.59C10.22,12.15 9.89,12.76 9.64,13.4M18,15V12C17.5,12 13.5,12.16 13.05,16.2C14.61,16.75 15.43,18.47 14.88,20.03C14.33,21.59 12.61,22.41 11.05,21.86C9.5,21.3 8.67,19.59 9.22,18.03C9.5,17.17 10.2,16.5 11.05,16.2C11.34,12.61 14.4,9.88 18,10V7L22,11L18,15M13,19A1,1 0 0,0 12,18A1,1 0 0,0 11,19A1,1 0 0,0 12,20A1,1 0 0,0 13,19M11,11.12C11.58,10.46 12.25,9.89 13,9.43V5H16L12,1L8,5H11V11.12Z" />
</vector>

View File

@ -4,5 +4,5 @@
android:tint="?android:attr/colorControlNormal"
android:viewportWidth="24"
android:viewportHeight="24">
<path android:fillColor="#000" android:pathData="M21.9,4.26C21.64,3.55 20.96,3.07 20.2,3.07H20.19L18.46,3.07H3.81C3.07,3.07 2.39,3.54 2.12,4.24C2.04,4.45 2,4.66 2,4.88V10.92L2.07,12.12C2.36,14.85 3.78,17.23 5.97,18.9C6,18.93 6.05,18.96 6.09,19H6.11C7.29,19.86 8.6,20.44 10,20.73C10.68,20.86 11.35,20.93 12,20.93C12.63,20.93 13.25,20.87 13.85,20.76C13.93,20.75 14,20.73 14.07,20.72C14.09,20.71 14.11,20.7 14.14,20.69C15.5,20.4 16.76,19.83 17.89,19H17.91C17.95,18.96 18,18.93 18.03,18.9C20.22,17.23 21.64,14.85 21.93,12.12L22,10.92V4.88C22,4.68 21.97,4.47 21.9,4.26M17.67,10.55L12.96,15.06C12.7,15.32 12.35,15.44 12,15.44C11.67,15.44 11.33,15.32 11.06,15.06L6.36,10.55C5.81,10.03 5.79,9.16 6.32,8.61C6.84,8.06 7.71,8.05 8.26,8.57L12,12.17L15.77,8.57C16.31,8.05 17.18,8.07 17.71,8.61C18.23,9.16 18.21,10.03 17.67,10.55Z" />
<path android:fillColor="?android:attr/colorPrimary" android:pathData="M21.9,4.26C21.64,3.55 20.96,3.07 20.2,3.07H20.19L18.46,3.07H3.81C3.07,3.07 2.39,3.54 2.12,4.24C2.04,4.45 2,4.66 2,4.88V10.92L2.07,12.12C2.36,14.85 3.78,17.23 5.97,18.9C6,18.93 6.05,18.96 6.09,19H6.11C7.29,19.86 8.6,20.44 10,20.73C10.68,20.86 11.35,20.93 12,20.93C12.63,20.93 13.25,20.87 13.85,20.76C13.93,20.75 14,20.73 14.07,20.72C14.09,20.71 14.11,20.7 14.14,20.69C15.5,20.4 16.76,19.83 17.89,19H17.91C17.95,18.96 18,18.93 18.03,18.9C20.22,17.23 21.64,14.85 21.93,12.12L22,10.92V4.88C22,4.68 21.97,4.47 21.9,4.26M17.67,10.55L12.96,15.06C12.7,15.32 12.35,15.44 12,15.44C11.67,15.44 11.33,15.32 11.06,15.06L6.36,10.55C5.81,10.03 5.79,9.16 6.32,8.61C6.84,8.06 7.71,8.05 8.26,8.57L12,12.17L15.77,8.57C16.31,8.05 17.18,8.07 17.71,8.61C18.23,9.16 18.21,10.03 17.67,10.55Z" />
</vector>

View File

@ -7,9 +7,9 @@
android:viewportHeight="46.0">
<path android:fillColor="?android:attr/colorAccent" android:pathData="M20,20m-19.5,0a19.5,19.5 0,1 1,39 0a19.5,19.5 0,1 1,-39 0" />
<path android:fillColor="#00000000" android:pathData="M20.0003,20.0038m-16.3277,6.4349a17.55,17.55 113.49,1 1,32.6554 -12.8699a17.55,17.55 113.49,1 1,-32.6554 12.8699" android:strokeColor="#ff0bbbef" android:strokeWidth="0.28" android:strokeAlpha="0.0" android:fillAlpha="0.0" />
<path android:fillColor="#ffffffff" android:pathData="M10.7614,17.0817L16.1565,11.2698A2,2 64.8053,0 1,18.983 11.1647L32.7688,23.9618A2,2 93.8141,0 1,32.874 26.7883L27.4789,32.6002A2,2 85.2688,0 1,24.6524 32.7053L10.8666,19.9082A2,2 68.6013,0 1,10.7614 17.0817z" />
<path android:fillColor="?android:attr/colorPrimary" android:pathData="M10.7614,17.0817L16.1565,11.2698A2,2 64.8053,0 1,18.983 11.1647L32.7688,23.9618A2,2 93.8141,0 1,32.874 26.7883L27.4789,32.6002A2,2 85.2688,0 1,24.6524 32.7053L10.8666,19.9082A2,2 68.6013,0 1,10.7614 17.0817z" />
<path android:fillColor="?android:attr/colorAccent" android:pathData="M24.36,30.53l-3.43,0a1.48,1.48 0,0 1,-1.06 -0.44,1.46 1.46,0 0,1 -0.43,-1 1.48,1.48 0,0 1,1.24 -1.44l-2.6,0a1.47,1.47 0,0 1,-0.22 -2.92l-2.7,0a1.47,1.47 0,0 1,-0.22 -2.92H12a1.47,1.47 0,0 1,0 -2.94l11.72,0.06a0.87,0.87 0,0 0,0.87 -0.44,0.74 0.74,0 0,0 0.1,-0.37 1.21,1.21 0,0 0,-0.24 -0.64c-0.65,-1 -1.18,-1.77 -1.67,-2.54a2.15,2.15 0,0 1,-0.35 -1.18,2.08 2.08,0 0,1 0.76,-1.6 1,1 0,0 1,0.6 -0.24,0.94 0.94,0 0,1 0.61,0.26l1.31,1.21c1.76,1.63 4,3.66 6,5.6a3.94,3.94 0,0 1,1.29 3v1.57c0,0.61 0,1.33 -0.09,2.05a5.76,5.76 0,0 1,-5.32 5C26.87,30.52 25.75,30.53 24.36,30.53Z" />
<path android:fillColor="#ffffffff" android:pathData="M23.83,12.36a0.37,0.37 0,0 1,0.24 0.12l1.3,1.21c2,1.83 4,3.72 6,5.59a3.4,3.4 0,0 1,1.11 2.63v1.57a17.63,17.63 0,0 1,-0.09 2,5.19 5.19,0 0,1 -4.77,4.47c-0.92,0 -2.14,0 -3.29,0 -1.8,0 -3.43,0 -3.45,0a0.92,0.92 0,0 1,0 -1.83l2.07,0V27l-4.89,0a0.91,0.91 0,1 1,0 -1.82h0l4.89,0V24.12l-7.83,0a0.92,0.92 0,0 1,0 -1.83l7.84,0V21.2l-3.89,0h0l-7.08,0a0.92,0.92 0,0 1,0 -1.83h0l11.66,0.06h0.06a1.44,1.44 0,0 0,1.36 -0.72,1.33 1.33,0 0,0 0.17,-0.64 1.68,1.68 0,0 0,-0.34 -1c-0.65,-1 -1.18,-1.78 -1.66,-2.53a1.62,1.62 0,0 1,-0.26 -0.88,1.5 1.5,0 0,1 0.55,-1.17 0.43,0.43 0,0 1,0.25 -0.12m0,-1.11a1.44,1.44 0,0 0,-0.95 0.37,2.62 2.62,0 0,0 -1,2 2.66,2.66 0,0 0,0.43 1.49c0.49,0.76 1,1.57 1.68,2.54a0.64,0.64 0,0 1,0.14 0.33,0.27 0.27,0 0,1 0,0.11c0,0.07 -0.08,0.14 -0.38,0.14h-0.05L12.05,18.2a2,2 0,0 0,-2 2,2 2,0 0,0 2,2h1.33a2,2 0,0 0,1.81 2.93h1.11a2,2 0,0 0,1.8 2.93h1a2.1,2.1 0,0 0,-0.22 0.9,2 2,0 0,0 2,2h0l3.43,0c1.4,0 2.52,0 3.32,0a6.26,6.26 0,0 0,5.85 -5.47c0.08,-0.74 0.09,-1.48 0.1,-2.1V21.92a4.54,4.54 0,0 0,-1.47 -3.45c-2,-1.92 -4.16,-3.87 -6,-5.6l-1.31,-1.21a1.45,1.45 0,0 0,-1 -0.41Z" />
<path android:fillColor="?android:attr/colorPrimary" android:pathData="M23.83,12.36a0.37,0.37 0,0 1,0.24 0.12l1.3,1.21c2,1.83 4,3.72 6,5.59a3.4,3.4 0,0 1,1.11 2.63v1.57a17.63,17.63 0,0 1,-0.09 2,5.19 5.19,0 0,1 -4.77,4.47c-0.92,0 -2.14,0 -3.29,0 -1.8,0 -3.43,0 -3.45,0a0.92,0.92 0,0 1,0 -1.83l2.07,0V27l-4.89,0a0.91,0.91 0,1 1,0 -1.82h0l4.89,0V24.12l-7.83,0a0.92,0.92 0,0 1,0 -1.83l7.84,0V21.2l-3.89,0h0l-7.08,0a0.92,0.92 0,0 1,0 -1.83h0l11.66,0.06h0.06a1.44,1.44 0,0 0,1.36 -0.72,1.33 1.33,0 0,0 0.17,-0.64 1.68,1.68 0,0 0,-0.34 -1c-0.65,-1 -1.18,-1.78 -1.66,-2.53a1.62,1.62 0,0 1,-0.26 -0.88,1.5 1.5,0 0,1 0.55,-1.17 0.43,0.43 0,0 1,0.25 -0.12m0,-1.11a1.44,1.44 0,0 0,-0.95 0.37,2.62 2.62,0 0,0 -1,2 2.66,2.66 0,0 0,0.43 1.49c0.49,0.76 1,1.57 1.68,2.54a0.64,0.64 0,0 1,0.14 0.33,0.27 0.27,0 0,1 0,0.11c0,0.07 -0.08,0.14 -0.38,0.14h-0.05L12.05,18.2a2,2 0,0 0,-2 2,2 2,0 0,0 2,2h1.33a2,2 0,0 0,1.81 2.93h1.11a2,2 0,0 0,1.8 2.93h1a2.1,2.1 0,0 0,-0.22 0.9,2 2,0 0,0 2,2h0l3.43,0c1.4,0 2.52,0 3.32,0a6.26,6.26 0,0 0,5.85 -5.47c0.08,-0.74 0.09,-1.48 0.1,-2.1V21.92a4.54,4.54 0,0 0,-1.47 -3.45c-2,-1.92 -4.16,-3.87 -6,-5.6l-1.31,-1.21a1.45,1.45 0,0 0,-1 -0.41Z" />
<path android:fillColor="?android:attr/colorAccent" android:pathData="M16.28,16.52m-1.42,0a1.42,1.42 0,1 1,2.84 0a1.42,1.42 0,1 1,-2.84 0" />
<path android:fillColor="?android:attr/colorAccent" android:pathData="M16.28,15.47a1.06,1.06 0,1 1,-1.06 1,1 1,0 0,1 1.06,-1m0,-0.74a1.8,1.8 0,1 0,1.79 1.79,1.8 1.8,0 0,0 -1.79,-1.79Z" />
<path android:strokeColor="@color/chop" android:pathData="M7.39,18.49a1,1 0,0 1,-1 -0.9A9.8,9.8 0,0 1,9.1 10.11,9.43 9.43,0 0,1 15.9,7a1,1 0,0 1,0 2h0a7.34,7.34 0,0 0,-5.31 2.47,7.79 7.79,0 0,0 -2.17,6 1,1 0,0 1,-0.9 1.07Z" />

View File

@ -7,14 +7,14 @@
android:viewportHeight="46.0">
<path android:fillColor="?android:attr/colorAccent" android:pathData="M20,20m-19.5,0a19.5,19.5 0,1 1,39 0a19.5,19.5 0,1 1,-39 0" />
<path android:fillColor="#00000000" android:pathData="M20.0003,20.0038m-16.3277,6.4349a17.55,17.55 113.49,1 1,32.6554 -12.8699a17.55,17.55 113.49,1 1,-32.6554 12.8699" android:strokeColor="#ff0bbbef" android:strokeWidth="0.28" android:strokeAlpha="0.0" android:fillAlpha="0.0" />
<path android:fillColor="#ffffffff" android:pathData="M31.45,30v0.7H8.63V30A1.41,1.41 0,0 1,10 28.57h20A1.41,1.41 0,0 1,31.45 30Z" />
<path android:fillColor="#ffffffff" android:pathData="M18,25.93a0.82,0.82 0,0 1,-0.64 -0.33,2.69 2.69,0 0,1 -0.25,-3l2.24,-3.92h0.32c0.46,0 0.54,0.36 0.62,0.79 0,0.2 0.1,0.48 0.15,0.77 0.11,0.59 0.23,1.21 0.27,1.4a0.71,0.71 0,0 1,-0.08 0.47l-0.25,0.46 -1.07,1.89 -0.6,1.07A0.8,0.8 0,0 1,18 25.93Z" android:strokeAlpha="0.0" android:fillAlpha="0.0" />
<path android:fillColor="?android:attr/colorPrimary" android:pathData="M31.45,30v0.7H8.63V30A1.41,1.41 0,0 1,10 28.57h20A1.41,1.41 0,0 1,31.45 30Z" />
<path android:fillColor="?android:attr/colorPrimary" android:pathData="M18,25.93a0.82,0.82 0,0 1,-0.64 -0.33,2.69 2.69,0 0,1 -0.25,-3l2.24,-3.92h0.32c0.46,0 0.54,0.36 0.62,0.79 0,0.2 0.1,0.48 0.15,0.77 0.11,0.59 0.23,1.21 0.27,1.4a0.71,0.71 0,0 1,-0.08 0.47l-0.25,0.46 -1.07,1.89 -0.6,1.07A0.8,0.8 0,0 1,18 25.93Z" android:strokeAlpha="0.0" android:fillAlpha="0.0" />
<path android:fillColor="#ff939ba3" android:pathData="M19.63,19.2s0.42,2.13 0.49,2.5a0.12,0.12 0,0 1,0 0.1l-0.25,0.47 -1.06,1.87 -0.6,1.08a0.27,0.27 0,0 1,-0.23 0.15,0.29 0.29,0 0,1 -0.21,-0.11 2.18,2.18 0,0 1,-0.2 -2.43l2.08,-3.63h0m0,-1.12H19l-0.32,0.56 -2.08,3.64A3.27,3.27 0,0 0,16.88 26a1.41,1.41 0,0 0,1.08 0.54,1.36 1.36,0 0,0 1.2,-0.73l0.6,-1.08 1.06,-1.87h0l0.25,-0.46a1.32,1.32 0,0 0,0.14 -0.85c0,-0.18 -0.16,-0.81 -0.27,-1.39 -0.06,-0.29 -0.11,-0.57 -0.15,-0.78a2.07,2.07 0,0 0,-0.06 -0.26,1.13 1.13,0 0,0 -1.11,-1Z" android:strokeAlpha="0.0" android:fillAlpha="0.0" />
<path android:fillColor="?android:attr/colorAccent" android:pathData="M20,25.93a0.89,0.89 0,0 1,-0.51 -0.17,2.71 2.71,0 0,1 -1,-2.88l1.18,-4.47h0.47c0.31,0 0.34,0.06 1,1.33L21.65,21a0.72,0.72 0,0 1,0.05 0.48l-0.13,0.51L21,24.1l-0.3,1.2A0.8,0.8 0,0 1,20 25.93Z" />
<path android:fillColor="#ffffffff" android:pathData="M20,19s0.95,2 1.12,2.29a0.17,0.17 0,0 1,0 0.1l-0.13,0.52L20.49,24l-0.3,1.2a0.23,0.23 0,0 1,-0.23 0.21,0.32 0.32,0 0,1 -0.18,-0.06A2.16,2.16 0,0 1,19 23L20,19h0m0,-1.12h-0.86l-0.22,0.83 -1.07,4.05a3.28,3.28 0,0 0,1.24 3.48,1.44 1.44,0 0,0 0.84,0.28 1.36,1.36 0,0 0,1.31 -1.06l0.3,-1.2 0.54,-2.08h0l0.12,-0.51a1.24,1.24 0,0 0,-0.09 -0.85l-0.62,-1.28c-0.13,-0.27 -0.25,-0.52 -0.35,-0.71 -0.2,-0.42 -0.45,-0.94 -1.15,-0.94Z" />
<path android:fillColor="?android:attr/colorPrimary" android:pathData="M20,19s0.95,2 1.12,2.29a0.17,0.17 0,0 1,0 0.1l-0.13,0.52L20.49,24l-0.3,1.2a0.23,0.23 0,0 1,-0.23 0.21,0.32 0.32,0 0,1 -0.18,-0.06A2.16,2.16 0,0 1,19 23L20,19h0m0,-1.12h-0.86l-0.22,0.83 -1.07,4.05a3.28,3.28 0,0 0,1.24 3.48,1.44 1.44,0 0,0 0.84,0.28 1.36,1.36 0,0 0,1.31 -1.06l0.3,-1.2 0.54,-2.08h0l0.12,-0.51a1.24,1.24 0,0 0,-0.09 -0.85l-0.62,-1.28c-0.13,-0.27 -0.25,-0.52 -0.35,-0.71 -0.2,-0.42 -0.45,-0.94 -1.15,-0.94Z" />
<path android:fillColor="?android:attr/colorAccent" android:pathData="M22.21,25.93a1,1 0,0 1,-0.33 -0.06,2.71 2.71,0 0,1 -1.73,-2.52l0,-4.74h0.58c0.25,0 0.3,0.07 2.07,2.12a0.72,0.72 0,0 1,0.18 0.45v2.69l0,1.23a0.81,0.81 0,0 1,-0.23 0.61A0.77,0.77 0,0 1,22.21 25.93Z" />
<path android:fillColor="#ffffffff" android:pathData="M20.69,19.16s1.43,1.64 1.67,1.92a0.21,0.21 0,0 1,0 0.1v0.53l0,2.15 0,1.24a0.24,0.24 0,0 1,-0.24 0.27l-0.12,0a2.17,2.17 0,0 1,-1.39 -2V19.16h0m0,-1.12H19.57v1.12l0,4.19a3.26,3.26 0,0 0,2.09 3,1.66 1.66,0 0,0 0.53,0.1 1.31,1.31 0,0 0,1 -0.4,1.36 1.36,0 0,0 0.39,-1l0,-1.24 0,-2.15h0v-0.52a1.22,1.22 0,0 0,-0.3 -0.8l-0.93,-1.07 -0.52,-0.6c-0.33,-0.38 -0.56,-0.65 -1.07,-0.65Z" />
<path android:fillColor="?android:attr/colorPrimary" android:pathData="M20.69,19.16s1.43,1.64 1.67,1.92a0.21,0.21 0,0 1,0 0.1v0.53l0,2.15 0,1.24a0.24,0.24 0,0 1,-0.24 0.27l-0.12,0a2.17,2.17 0,0 1,-1.39 -2V19.16h0m0,-1.12H19.57v1.12l0,4.19a3.26,3.26 0,0 0,2.09 3,1.66 1.66,0 0,0 0.53,0.1 1.31,1.31 0,0 0,1 -0.4,1.36 1.36,0 0,0 0.39,-1l0,-1.24 0,-2.15h0v-0.52a1.22,1.22 0,0 0,-0.3 -0.8l-0.93,-1.07 -0.52,-0.6c-0.33,-0.38 -0.56,-0.65 -1.07,-0.65Z" />
<path android:fillColor="?android:attr/colorAccent" android:pathData="M13.6,25.93a0.91,0.91 0,0 1,-0.61 -0.27L11.81,24.5c-0.86,-0.84 -1,-1 -1.18,-1.11s-0.36,-0.3 -1.29,-1.23a4.75,4.75 0,0 1,-1.55 -3.28,4.73 4.73,0 0,1 1.59,-3.34l0.07,-0.07c0.64,-0.64 1.84,-1.84 2.34,-2.26a4,4 0,0 1,2.59 -0.93,5.62 5.62,0 0,1 3.72,1.59c1.3,1.2 8.42,8.3 10.57,10.45a0.88,0.88 0,0 1,0.26 0.86,0.85 0.85,0 0,1 -0.66,0.59h0a3,3 0,0 1,-0.89 0.15h0a2.75,2.75 0,0 1,-2 -0.86l-4.66,-4.38a2.15,2.15 0,0 0,-1.46 -0.58H14.45a0.74,0.74 0,0 0,-0.72 0.36,0.7 0.7,0 0,0 -0.1,0.32 10.39,10.39 0,0 0,1 2.3,2.06 2.06,0 0,1 0.3,1.13 2,2 0,0 1,-0.76 1.49A0.91,0.91 0,0 1,13.6 25.93Z" />
<path android:fillColor="#ffffffff" android:pathData="M14.38,12.84a5,5 0,0 1,3.34 1.44C19,15.49 26.5,23 28.28,24.72c0.21,0.21 0.15,0.44 -0.15,0.51a2.39,2.39 0,0 1,-0.78 0.14,2.18 2.18,0 0,1 -1.56,-0.69l-4.67,-4.4a2.73,2.73 0,0 0,-1.84 -0.72H14.45a1.3,1.3 0,0 0,-1.2 0.63,1.27 1.27,0 0,0 -0.18,0.59 9.8,9.8 0,0 0,1.08 2.6,1.49 1.49,0 0,1 0.22,0.82 1.4,1.4 0,0 1,-0.54 1.07,0.43 0.43,0 0,1 -0.23,0.1 0.31,0.31 0,0 1,-0.22 -0.11L12.2,24.1c-1.78,-1.75 -0.67,-0.55 -2.47,-2.33 -0.67,-0.67 -2.76,-3 0,-5.84 0.59,-0.58 1.88,-1.88 2.38,-2.29a3.42,3.42 0,0 1,2.23 -0.8m0,-1.12a4.59,4.59 0,0 0,-2.94 1.06c-0.46,0.38 -1.42,1.33 -2.39,2.3L9,15.15a5.24,5.24 0,0 0,-1.76 3.73,5.28 5.28,0 0,0 1.71,3.68c1,0.94 1.13,1.09 1.33,1.25s0.31,0.26 1.15,1.09l1.18,1.15a1.39,1.39 0,0 0,1 0.44,1.51 1.51,0 0,0 0.91,-0.34 2.5,2.5 0,0 0,1 -1.91,2.63 2.63,0 0,0 -0.37,-1.44 11.28,11.28 0,0 1,-0.91 -2v0s0,-0.08 0.24,-0.08h4.83a1.53,1.53 0,0 1,1.07 0.43L25,25.48a3.28,3.28 0,0 0,2.33 1,3.4 3.4,0 0,0 1.06,-0.18h0a1.39,1.39 0,0 0,0.65 -2.38c-2.16,-2.15 -9.28,-9.26 -10.59,-10.47a6.15,6.15 0,0 0,-4.1 -1.74Z" />
<path android:fillColor="?android:attr/colorPrimary" android:pathData="M14.38,12.84a5,5 0,0 1,3.34 1.44C19,15.49 26.5,23 28.28,24.72c0.21,0.21 0.15,0.44 -0.15,0.51a2.39,2.39 0,0 1,-0.78 0.14,2.18 2.18,0 0,1 -1.56,-0.69l-4.67,-4.4a2.73,2.73 0,0 0,-1.84 -0.72H14.45a1.3,1.3 0,0 0,-1.2 0.63,1.27 1.27,0 0,0 -0.18,0.59 9.8,9.8 0,0 0,1.08 2.6,1.49 1.49,0 0,1 0.22,0.82 1.4,1.4 0,0 1,-0.54 1.07,0.43 0.43,0 0,1 -0.23,0.1 0.31,0.31 0,0 1,-0.22 -0.11L12.2,24.1c-1.78,-1.75 -0.67,-0.55 -2.47,-2.33 -0.67,-0.67 -2.76,-3 0,-5.84 0.59,-0.58 1.88,-1.88 2.38,-2.29a3.42,3.42 0,0 1,2.23 -0.8m0,-1.12a4.59,4.59 0,0 0,-2.94 1.06c-0.46,0.38 -1.42,1.33 -2.39,2.3L9,15.15a5.24,5.24 0,0 0,-1.76 3.73,5.28 5.28,0 0,0 1.71,3.68c1,0.94 1.13,1.09 1.33,1.25s0.31,0.26 1.15,1.09l1.18,1.15a1.39,1.39 0,0 0,1 0.44,1.51 1.51,0 0,0 0.91,-0.34 2.5,2.5 0,0 0,1 -1.91,2.63 2.63,0 0,0 -0.37,-1.44 11.28,11.28 0,0 1,-0.91 -2v0s0,-0.08 0.24,-0.08h4.83a1.53,1.53 0,0 1,1.07 0.43L25,25.48a3.28,3.28 0,0 0,2.33 1,3.4 3.4,0 0,0 1.06,-0.18h0a1.39,1.39 0,0 0,0.65 -2.38c-2.16,-2.15 -9.28,-9.26 -10.59,-10.47a6.15,6.15 0,0 0,-4.1 -1.74Z" />
<path android:strokeColor="@color/flip" android:pathData="M31.53,26.46a1.23,1.23 0,0 1,-1.23 -1.09c0,-0.32 0,-1.91 0,-2.82 0.06,-4.2 -2.87,-9.83 -6.72,-10.79a1.24,1.24 0,0 1,0.6 -2.4c4.66,1.16 8.68,7.34 8.6,13.22 0,2 0,2.49 0,2.54a1.24,1.24 0,0 1,-1.09 1.34Z" />
</vector>

View File

@ -6,11 +6,11 @@
android:viewportWidth="46.0"
android:viewportHeight="46.0">
<path android:fillColor="?android:attr/colorAccent" android:pathData="M20,20m-19.5,0a19.5,19.5 0,1 1,39 0a19.5,19.5 0,1 1,-39 0" />
<path android:fillColor="#ffffffff" android:pathData="M13.6,18l4.9,-4.9c0.8,-0.8 2,-0.8 2.8,0L33.2,25c0.8,0.8 0.8,2 0,2.8l-4.9,4.9c-0.8,0.8 -2,0.8 -2.8,0L13.6,20.8C12.8,20 12.8,18.7 13.6,18z" />
<path android:fillColor="?android:attr/colorPrimary" android:pathData="M13.6,18l4.9,-4.9c0.8,-0.8 2,-0.8 2.8,0L33.2,25c0.8,0.8 0.8,2 0,2.8l-4.9,4.9c-0.8,0.8 -2,0.8 -2.8,0L13.6,20.8C12.8,20 12.8,18.7 13.6,18z" />
<path android:fillColor="?android:attr/colorAccent" android:pathData="M28.3,31.2c-2,0 -5.5,-0.2 -6.1,-0.2c-0.7,0 -1.3,-0.6 -1.3,-1.3c0,-0.7 0.5,-1.2 1.2,-1.3l-2.4,-0.1c-0.4,0 -0.7,-0.2 -0.9,-0.4c-0.3,-0.3 -0.4,-0.6 -0.4,-1c0,-0.7 0.5,-1.2 1.2,-1.3l-2.5,-0.1c-0.7,-0.1 -1.2,-0.8 -1.1,-1.5c0.1,-0.5 0.5,-1 1,-1.1l-2.6,-0.1c-0.4,0 -0.7,-0.2 -0.9,-0.4c-0.2,-0.3 -0.4,-0.6 -0.4,-1c0.1,-0.7 0.6,-1.2 1.3,-1.2h0.1l10.6,0.5h0.1c0.3,0 0.6,-0.1 0.7,-0.4c0.1,-0.1 0.1,-0.2 0.1,-0.3c0,-0.2 -0.1,-0.4 -0.2,-0.6c-0.6,-0.9 -1,-1.7 -1.4,-2.4c-0.2,-0.3 -0.3,-0.7 -0.3,-1.1c0,-0.6 0.3,-1.1 0.8,-1.4c0.2,-0.1 0.3,-0.2 0.5,-0.2c0.2,0 0.4,0.1 0.6,0.3l1.2,1.1l5.3,5.3c0.7,0.7 1.1,1.8 1.1,2.8v0.1c0,0.2 0,0.4 0,0.7v0.1c0,0.2 0,0.3 0,0.5c0,0.6 -0.1,1.2 -0.2,1.9C32.9,29.3 30.9,31.1 28.3,31.2L28.3,31.2z" />
<path android:fillColor="#ffffffff" android:pathData="M25.4,14.6c0.1,0 0.2,0.1 0.2,0.1l1.1,1.1l5.3,5.3c0.6,0.6 1,1.5 0.9,2.4v0.1v0.7c0,0.2 0,0.4 0,0.6c0,0.5 -0.1,1.2 -0.2,1.8c-0.4,2.2 -2.3,3.8 -4.5,3.9l0,0c-2.1,0 -6.1,-0.2 -6.1,-0.2c-0.5,0 -0.8,-0.4 -0.8,-0.8c0,-0.5 0.4,-0.8 0.8,-0.8l0,0l1.9,0.1v-1l-4.5,-0.2c-0.5,-0.1 -0.8,-0.5 -0.7,-0.9c0,-0.4 0.4,-0.7 0.7,-0.7l0,0l4.5,0.2v-1l-7,-0.3c-0.5,0 -0.8,-0.4 -0.8,-0.8c0,-0.5 0.4,-0.8 0.8,-0.8l0,0l7.1,0.3v-1l-3.5,-0.1l0,0l-6.4,-0.3c-0.5,-0.1 -0.8,-0.5 -0.7,-0.9c0,-0.4 0.4,-0.7 0.7,-0.7l0,0L25.1,21h0.1c0.5,0 0.9,-0.2 1.2,-0.6c0.1,-0.2 0.2,-0.4 0.2,-0.6c0,-0.3 -0.1,-0.6 -0.3,-0.9c-0.6,-0.9 -1,-1.7 -1.4,-2.4c-0.1,-0.2 -0.2,-0.5 -0.2,-0.8c0,-0.4 0.2,-0.8 0.5,-1.1C25.3,14.6 25.3,14.6 25.4,14.6M25.4,13.6c-0.3,0 -0.6,0.1 -0.8,0.3c-0.6,0.4 -0.9,1.1 -0.9,1.8c0,0.4 0.1,0.9 0.4,1.3c0.4,0.7 0.9,1.5 1.4,2.4c0.1,0.1 0.1,0.2 0.1,0.3c0,0 0,0.1 0,0.1c0,0.1 -0.1,0.1 -0.3,0.1h-0.1l-10.6,-0.5h-0.1c-1,0 -1.8,0.8 -1.9,1.8c0,1 0.8,1.9 1.8,1.9l1.2,0c-0.5,0.9 -0.2,2 0.6,2.5c0.3,0.2 0.6,0.3 0.9,0.3h1c-0.1,0.2 -0.2,0.5 -0.2,0.8c0,0.5 0.2,1 0.5,1.3c0.3,0.4 0.8,0.6 1.3,0.6h0.9c-0.1,0.2 -0.2,0.5 -0.2,0.8c0,1 0.8,1.9 1.8,1.9l0,0c0.7,0 4.2,0.2 6.2,0.2l0,0c2.7,0 5.1,-2 5.5,-4.7c0.1,-0.7 0.1,-1.4 0.2,-1.9c0,-0.2 0,-0.4 0,-0.5v-0.1c0,-0.2 0,-0.4 0,-0.7v-0.1c0.1,-1.2 -0.4,-2.4 -1.2,-3.2l-5.3,-5.4L26.4,14C26.1,13.7 25.8,13.6 25.4,13.6L25.4,13.6z" />
<path android:fillColor="?android:attr/colorPrimary" android:pathData="M25.4,14.6c0.1,0 0.2,0.1 0.2,0.1l1.1,1.1l5.3,5.3c0.6,0.6 1,1.5 0.9,2.4v0.1v0.7c0,0.2 0,0.4 0,0.6c0,0.5 -0.1,1.2 -0.2,1.8c-0.4,2.2 -2.3,3.8 -4.5,3.9l0,0c-2.1,0 -6.1,-0.2 -6.1,-0.2c-0.5,0 -0.8,-0.4 -0.8,-0.8c0,-0.5 0.4,-0.8 0.8,-0.8l0,0l1.9,0.1v-1l-4.5,-0.2c-0.5,-0.1 -0.8,-0.5 -0.7,-0.9c0,-0.4 0.4,-0.7 0.7,-0.7l0,0l4.5,0.2v-1l-7,-0.3c-0.5,0 -0.8,-0.4 -0.8,-0.8c0,-0.5 0.4,-0.8 0.8,-0.8l0,0l7.1,0.3v-1l-3.5,-0.1l0,0l-6.4,-0.3c-0.5,-0.1 -0.8,-0.5 -0.7,-0.9c0,-0.4 0.4,-0.7 0.7,-0.7l0,0L25.1,21h0.1c0.5,0 0.9,-0.2 1.2,-0.6c0.1,-0.2 0.2,-0.4 0.2,-0.6c0,-0.3 -0.1,-0.6 -0.3,-0.9c-0.6,-0.9 -1,-1.7 -1.4,-2.4c-0.1,-0.2 -0.2,-0.5 -0.2,-0.8c0,-0.4 0.2,-0.8 0.5,-1.1C25.3,14.6 25.3,14.6 25.4,14.6M25.4,13.6c-0.3,0 -0.6,0.1 -0.8,0.3c-0.6,0.4 -0.9,1.1 -0.9,1.8c0,0.4 0.1,0.9 0.4,1.3c0.4,0.7 0.9,1.5 1.4,2.4c0.1,0.1 0.1,0.2 0.1,0.3c0,0 0,0.1 0,0.1c0,0.1 -0.1,0.1 -0.3,0.1h-0.1l-10.6,-0.5h-0.1c-1,0 -1.8,0.8 -1.9,1.8c0,1 0.8,1.9 1.8,1.9l1.2,0c-0.5,0.9 -0.2,2 0.6,2.5c0.3,0.2 0.6,0.3 0.9,0.3h1c-0.1,0.2 -0.2,0.5 -0.2,0.8c0,0.5 0.2,1 0.5,1.3c0.3,0.4 0.8,0.6 1.3,0.6h0.9c-0.1,0.2 -0.2,0.5 -0.2,0.8c0,1 0.8,1.9 1.8,1.9l0,0c0.7,0 4.2,0.2 6.2,0.2l0,0c2.7,0 5.1,-2 5.5,-4.7c0.1,-0.7 0.1,-1.4 0.2,-1.9c0,-0.2 0,-0.4 0,-0.5v-0.1c0,-0.2 0,-0.4 0,-0.7v-0.1c0.1,-1.2 -0.4,-2.4 -1.2,-3.2l-5.3,-5.4L26.4,14C26.1,13.7 25.8,13.6 25.4,13.6L25.4,13.6z" />
<path android:strokeColor="@color/pick" android:pathData="M13.5,33.3c-0.5,0 -0.9,-0.4 -0.9,-0.9c0,0 0,0 0,0v-7.2c-0.1,-0.5 0.3,-0.9 0.8,-1s0.9,0.3 1,0.8c0,0.1 0,0.1 0,0.2v7.2C14.4,32.9 14,33.3 13.5,33.3z" />
<path android:strokeColor="@color/pick2" android:pathData="M16.3,33.4c-0.5,0 -0.9,-0.4 -0.9,-0.9v-4.7c-0.1,-0.5 0.3,-0.9 0.8,-1c0.5,-0.1 0.9,0.3 1,0.8c0,0.1 0,0.1 0,0.2v4.7C17.2,33 16.8,33.4 16.3,33.4z" />
<path android:strokeColor="@color/pick3" android:pathData="M19,33.4c-0.5,0 -0.9,-0.4 -0.9,-0.9v-2c0.1,-0.5 0.5,-0.9 1,-0.8c0.4,0 0.8,0.4 0.8,0.8v2C19.9,33 19.5,33.4 19,33.4C19,33.4 19,33.4 19,33.4z" />
<path android:fillColor="#ffffffff" android:pathData="M14.1,14.1L8.5,8.3L7.4,7.1L6.8,7.7L8.1,9l0,0c-0.2,0.5 -0.4,1 -0.4,1.6v2.3l-0.9,0.9v0.5h6.3l0.9,0.9l0.6,-0.6L14.1,14.1zM10.4,15.6c0.5,0 0.9,-0.4 0.9,-0.9c0,0 0,0 0,0H9.5C9.5,15.2 9.9,15.6 10.4,15.6C10.4,15.6 10.4,15.6 10.4,15.6zM13.2,12.2v-1.7c0.1,-1.3 -0.8,-2.6 -2.1,-2.9V7.3c0,-0.4 -0.3,-0.7 -0.7,-0.7c-0.4,0 -0.7,0.3 -0.7,0.7v0.3H9.6L9.4,7.7l0,0L9.1,7.8l0,0L13.2,12.2z" />
<path android:fillColor="?android:attr/colorPrimary" android:pathData="M14.1,14.1L8.5,8.3L7.4,7.1L6.8,7.7L8.1,9l0,0c-0.2,0.5 -0.4,1 -0.4,1.6v2.3l-0.9,0.9v0.5h6.3l0.9,0.9l0.6,-0.6L14.1,14.1zM10.4,15.6c0.5,0 0.9,-0.4 0.9,-0.9c0,0 0,0 0,0H9.5C9.5,15.2 9.9,15.6 10.4,15.6C10.4,15.6 10.4,15.6 10.4,15.6zM13.2,12.2v-1.7c0.1,-1.3 -0.8,-2.6 -2.1,-2.9V7.3c0,-0.4 -0.3,-0.7 -0.7,-0.7c-0.4,0 -0.7,0.3 -0.7,0.7v0.3H9.6L9.4,7.7l0,0L9.1,7.8l0,0L13.2,12.2z" />
</vector>

View File

@ -7,8 +7,8 @@
android:viewportHeight="46.0">
<path android:fillColor="?android:attr/colorAccent" android:pathData="M20,20m-19.5,0a19.5,19.5 0,1 1,39 0a19.5,19.5 0,1 1,-39 0" />
<path android:fillColor="#00000000" android:pathData="M20.0003,20.0038m-16.3277,6.4349a17.55,17.55 113.49,1 1,32.6554 -12.8699a17.55,17.55 113.49,1 1,-32.6554 12.8699" android:strokeColor="#ff0bbbef" android:strokeWidth="0.28" android:strokeAlpha="0.0" android:fillAlpha="0.0" />
<path android:fillColor="#ffffffff" android:pathData="M15.81,26.74l8.38,0a2.11,2.11 0,0 0,2.11 -2.1V6.06A2.11,2.11 0,0 0,24.19 4l-8.38,0A2.12,2.12 0,0 0,13.7 6v18.6A2.12,2.12 0,0 0,15.81 26.74Z" />
<path android:fillColor="?android:attr/colorPrimary" android:pathData="M15.81,26.74l8.38,0a2.11,2.11 0,0 0,2.11 -2.1V6.06A2.11,2.11 0,0 0,24.19 4l-8.38,0A2.12,2.12 0,0 0,13.7 6v18.6A2.12,2.12 0,0 0,15.81 26.74Z" />
<path android:fillColor="?android:attr/colorAccent" android:pathData="M14.58,24.42l10.84,0.04l0,-18.25l-10.84,-0.04l0,18.25z" />
<path android:fillColor="?android:attr/colorAccent" android:pathData="M14.46,34a5.51,5.51 0,0 1,-1.66 -3.63c-0.09,-2.3 -0.09,-6.64 -0.09,-6.95a1.47,1.47 0,0 1,2.51 -1.06,1.51 1.51,0 0,1 0.41,0.75l0,-6.91a1.47,1.47 0,0 1,1.47 -1.47,1.44 1.44,0 0,1 1,0.43 1.38,1.38 0,0 1,0.42 0.86v-1.7a1.47,1.47 0,0 1,2.51 -1,1.48 1.48,0 0,1 0.43,1v0.81a1.47,1.47 0,0 1,2.51 -1,1.42 1.42,0 0,1 0.43,1l0,11.22a1.06,1.06 0,0 0,0.24 0.78,1 1,0 0,0 0.2,0.14 0.77,0.77 0,0 0,0.38 0.1,1.11 1.11,0 0,0 0.63,-0.25c1,-0.66 1.77,-1.19 2.53,-1.69A2.15,2.15 0,0 1,29.6 25a2.08,2.08 0,0 1,1.48 0.6l0.12,0.14a0.85,0.85 0,0 1,0 1.22L30,28.3c-1.7,1.88 -3.63,4 -5.54,6.08a4,4 0,0 1,-3 1.31H19.85a18.29,18.29 0,0 1,-2 -0.07A5.55,5.55 0,0 1,14.46 34Z" />
<path android:fillColor="#ffffffff" android:pathData="M23.59,14.44a0.93,0.93 0,0 1,0.27 0.64l0,11.22a1.57,1.57 0,0 0,0.41 1.17,1.4 1.4,0 0,0 0.33,0.24 1.33,1.33 0,0 0,0.64 0.17,1.71 1.71,0 0,0 0.95,-0.35c1,-0.66 1.77,-1.19 2.51,-1.68a1.64,1.64 0,0 1,0.88 -0.26,1.49 1.49,0 0,1 1.09,0.44l0.09,0.1a0.31,0.31 0,0 1,0 0.48l-1.2,1.32C27.77,29.92 25.89,32 24,34a3.46,3.46 0,0 1,-2.62 1.14H19.85c-0.59,0 -1.29,0 -2,-0.08a5.17,5.17 0,0 1,-4.5 -4.73c-0.09,-2.34 -0.09,-6.91 -0.09,-6.94a0.91,0.91 0,0 1,1.56 -0.65,0.93 0.93,0 0,1 0.27,0.62l0,2.27 1.09,-0.1 -0.05,-9.45a0.92,0.92 0,0 1,1.56 -0.55,1 1,0 0,1 0.27,0.65L18,25.63h1.09l-0.05,-11.32A0.92,0.92 0,0 1,20 13.4a0.88,0.88 0,0 1,0.64 0.27,0.89 0.89,0 0,1 0.27,0.62L21,25.62h1.09v-3.9h0V15.09a0.92,0.92 0,0 1,0.91 -0.92,1 1,0 0,1 0.65,0.27m0.79,-0.79a2.05,2.05 0,0 0,-1.44 -0.59,2 2,0 0,0 -1.13,0.34 1.93,1.93 0,0 0,-0.38 -0.52A2,2 0,0 0,18 14.32v0a2,2 0,0 0,-2.92 1.82v5.37a1.89,1.89 0,0 0,-0.88 -0.19,2 2,0 0,0 -1.44,0.6 2,2 0,0 0,-0.58 1.43v0c0,1.29 0,4.77 0.08,7a6.13,6.13 0,0 0,1.83 4,6 6,0 0,0 3.68,1.79 19.69,19.69 0,0 0,2.11 0.08h1.56a4.58,4.58 0,0 0,3.44 -1.49c1.9,-2.07 3.84,-4.2 5.55,-6.08l1.19,-1.32a1.4,1.4 0,0 0,0 -1.95l-0.16,-0.17a2.6,2.6 0,0 0,-1.87 -0.77,2.74 2.74,0 0,0 -1.49,0.45c-0.76,0.49 -1.56,1 -2.53,1.69a0.66,0.66 0,0 1,-0.33 0.16,0.22 0.22,0 0,1 -0.11,0 0.15,0.15 0,0 1,-0.06 -0.05A0.61,0.61 0,0 1,25 26.3l0,-11.22a2,2 0,0 0,-0.59 -1.43Z" />
<path android:fillColor="?android:attr/colorPrimary" android:pathData="M23.59,14.44a0.93,0.93 0,0 1,0.27 0.64l0,11.22a1.57,1.57 0,0 0,0.41 1.17,1.4 1.4,0 0,0 0.33,0.24 1.33,1.33 0,0 0,0.64 0.17,1.71 1.71,0 0,0 0.95,-0.35c1,-0.66 1.77,-1.19 2.51,-1.68a1.64,1.64 0,0 1,0.88 -0.26,1.49 1.49,0 0,1 1.09,0.44l0.09,0.1a0.31,0.31 0,0 1,0 0.48l-1.2,1.32C27.77,29.92 25.89,32 24,34a3.46,3.46 0,0 1,-2.62 1.14H19.85c-0.59,0 -1.29,0 -2,-0.08a5.17,5.17 0,0 1,-4.5 -4.73c-0.09,-2.34 -0.09,-6.91 -0.09,-6.94a0.91,0.91 0,0 1,1.56 -0.65,0.93 0.93,0 0,1 0.27,0.62l0,2.27 1.09,-0.1 -0.05,-9.45a0.92,0.92 0,0 1,1.56 -0.55,1 1,0 0,1 0.27,0.65L18,25.63h1.09l-0.05,-11.32A0.92,0.92 0,0 1,20 13.4a0.88,0.88 0,0 1,0.64 0.27,0.89 0.89,0 0,1 0.27,0.62L21,25.62h1.09v-3.9h0V15.09a0.92,0.92 0,0 1,0.91 -0.92,1 1,0 0,1 0.65,0.27m0.79,-0.79a2.05,2.05 0,0 0,-1.44 -0.59,2 2,0 0,0 -1.13,0.34 1.93,1.93 0,0 0,-0.38 -0.52A2,2 0,0 0,18 14.32v0a2,2 0,0 0,-2.92 1.82v5.37a1.89,1.89 0,0 0,-0.88 -0.19,2 2,0 0,0 -1.44,0.6 2,2 0,0 0,-0.58 1.43v0c0,1.29 0,4.77 0.08,7a6.13,6.13 0,0 0,1.83 4,6 6,0 0,0 3.68,1.79 19.69,19.69 0,0 0,2.11 0.08h1.56a4.58,4.58 0,0 0,3.44 -1.49c1.9,-2.07 3.84,-4.2 5.55,-6.08l1.19,-1.32a1.4,1.4 0,0 0,0 -1.95l-0.16,-0.17a2.6,2.6 0,0 0,-1.87 -0.77,2.74 2.74,0 0,0 -1.49,0.45c-0.76,0.49 -1.56,1 -2.53,1.69a0.66,0.66 0,0 1,-0.33 0.16,0.22 0.22,0 0,1 -0.11,0 0.15,0.15 0,0 1,-0.06 -0.05A0.61,0.61 0,0 1,25 26.3l0,-11.22a2,2 0,0 0,-0.59 -1.43Z" />
</vector>

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2015-2016 The CyanogenMod Project
Copyright (C) 2017,2022 The LineageOS Project
Copyright (C) 2017-2024 The LineageOS Project
Licensed under the Apache License, Version 2.0 (the "License"
you may not use this file except in compliance with the License.
@ -22,28 +22,28 @@
<PreferenceCategory
android:key="actions_key">
<SwitchPreference
<SwitchPreferenceCompat
android:key="gesture_chop_chop"
android:defaultValue="true"
android:title="@string/chop_chop_gesture_title"
android:summary="@string/chop_chop_gesture_summary"
android:icon="@drawable/ic_settings_chop" />
<SwitchPreference
<SwitchPreferenceCompat
android:key="gesture_ir_silencer"
android:defaultValue="false"
android:title="@string/hand_wave_silencer_title"
android:summary="@string/hand_wave_silencer_summary"
android:icon="@drawable/ic_settings_wave" />
<SwitchPreference
<SwitchPreferenceCompat
android:key="gesture_flip_to_mute"
android:defaultValue="false"
android:title="@string/flip_to_mute_title"
android:summary="@string/flip_to_mute_summary"
android:icon="@drawable/ic_settings_flip" />
<SwitchPreference
<SwitchPreferenceCompat
android:key="gesture_lift_to_silence"
android:defaultValue="false"
android:title="@string/lift_to_silence_title"

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2017-2022 The LineageOS Project
Copyright (C) 2017-2024 The LineageOS Project
Licensed under the Apache License, Version 2.0 (the "License"
you may not use this file except in compliance with the License.
@ -27,7 +27,7 @@
android:key="doze_enable"
android:title="@string/ambient_display_enable_title" />
<SwitchPreference
<SwitchPreferenceCompat
android:key="always_on_display"
android:disableDependentsState="true"
android:title="@string/ambient_display_always_on_title"
@ -38,21 +38,21 @@
android:key="ambient_display_key"
android:title="@string/ambient_display_title">
<SwitchPreference
<SwitchPreferenceCompat
android:key="gesture_pick_up"
android:defaultValue="true"
android:title="@string/pick_up_gesture_title"
android:summary="@string/pick_up_gesture_summary"
android:icon="@drawable/ic_pickup" />
<SwitchPreference
<SwitchPreferenceCompat
android:key="gesture_hand_wave"
android:defaultValue="true"
android:title="@string/hand_wave_gesture_title"
android:summary="@string/hand_wave_gesture_summary"
android:icon="@drawable/ic_hand" />
<SwitchPreference
<SwitchPreferenceCompat
android:key="gesture_pocket"
android:defaultValue="true"
android:title="@string/pocket_gesture_title"

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 2016 The CyanogenMod Project
* Copyright (c) 2017-2022 The LineageOS Project
* Copyright (c) 2017-2024 The LineageOS Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -20,7 +20,6 @@ package org.lineageos.settings.device;
import android.os.Bundle;
import com.android.settingslib.collapsingtoolbar.CollapsingToolbarBaseActivity;
import com.android.settingslib.collapsingtoolbar.R;
public class ActionsPreferenceActivity extends CollapsingToolbarBaseActivity {
@ -29,7 +28,8 @@ public class ActionsPreferenceActivity extends CollapsingToolbarBaseActivity {
super.onCreate(savedInstanceState);
getFragmentManager()
.beginTransaction()
.replace(R.id.content_frame, new ActionsPreferenceFragment())
.replace(com.android.settingslib.collapsingtoolbar.R.id.content_frame,
new ActionsPreferenceFragment())
.commit();
}
}

View File

@ -1,6 +1,6 @@
/*
* Copyright (C) 2015-2016 The CyanogenMod Project
* 2017,2022 The LineageOS Project
* 2017-2024 The LineageOS Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -20,7 +20,6 @@ package org.lineageos.settings.device;
import android.os.Bundle;
import com.android.settingslib.collapsingtoolbar.CollapsingToolbarBaseActivity;
import com.android.settingslib.collapsingtoolbar.R;
public class DozePreferenceActivity extends CollapsingToolbarBaseActivity {
@ -31,7 +30,8 @@ public class DozePreferenceActivity extends CollapsingToolbarBaseActivity {
super.onCreate(savedInstanceState);
getFragmentManager()
.beginTransaction()
.replace(R.id.content_frame, new DozePreferenceFragment(), TAG_DOZE)
.replace(com.android.settingslib.collapsingtoolbar.R.id.content_frame,
new DozePreferenceFragment(), TAG_DOZE)
.commit();
}
}

View File

@ -1,6 +1,6 @@
/*
* Copyright (C) 2015 The CyanogenMod Project
* Copyright (C) 2017-2022 The LineageOS Project
* Copyright (C) 2017-2024 The LineageOS Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -24,26 +24,26 @@ import android.app.DialogFragment;
import android.content.DialogInterface;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.widget.Switch;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
import androidx.preference.Preference;
import androidx.preference.PreferenceCategory;
import androidx.preference.PreferenceFragment;
import androidx.preference.SwitchPreference;
import androidx.preference.SwitchPreferenceCompat;
import com.android.settingslib.widget.MainSwitchPreference;
import com.android.settingslib.widget.OnMainSwitchChangeListener;
public class DozePreferenceFragment extends PreferenceFragment
implements Preference.OnPreferenceChangeListener, OnMainSwitchChangeListener {
implements Preference.OnPreferenceChangeListener, OnCheckedChangeListener {
private MainSwitchPreference mSwitchBar;
private SwitchPreference mAlwaysOnDisplayPreference;
private SwitchPreferenceCompat mAlwaysOnDisplayPreference;
private SwitchPreference mHandwavePreference;
private SwitchPreference mPickUpPreference;
private SwitchPreference mPocketPreference;
private SwitchPreferenceCompat mHandwavePreference;
private SwitchPreferenceCompat mPickUpPreference;
private SwitchPreferenceCompat mPocketPreference;
@Override
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
@ -97,7 +97,7 @@ public class DozePreferenceFragment extends PreferenceFragment
}
@Override
public void onSwitchChanged(Switch switchView, boolean isChecked) {
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
MotoActionsSettings.enableDoze(getActivity(), isChecked);
mSwitchBar.setChecked(isChecked);

18
MotoNrEnabler/Android.bp Normal file
View File

@ -0,0 +1,18 @@
//
// SPDX-FileCopyrightText: 2024 The LineageOS Project
// SPDX-License-Identifier: Apache-2.0
//
android_app {
name: "MotoNrEnabler",
srcs: [
"src/**/*.aidl",
"src/**/*.kt",
],
libs: ["telephony-common"],
certificate: "platform",
platform_apis: true,
system_ext_specific: true,
}

View File

@ -0,0 +1,29 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
SPDX-FileCopyrightText: 2024 The LineageOS Project
SPDX-License-Identifier: Apache-2.0
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="org.lineageos.motorola.nrenabler"
android:sharedUserId="android.uid.phone">
<uses-permission android:name="com.qualcomm.permission.USE_QCRIL_MSG_TUNNEL" />
<application
android:label="MotoNrEnabler"
android:persistent="true"
android:directBootAware="true">
<service
android:name=".NrEnablerService" />
<receiver
android:name=".BootCompletedReceiver"
android:exported="false">
<intent-filter>
<action android:name="android.intent.action.LOCKED_BOOT_COMPLETED" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</receiver>
</application>
</manifest>

View File

@ -0,0 +1,5 @@
package com.qualcomm.qcrilmsgtunnel;
interface IQcrilMsgTunnel {
int sendOemRilRequestRaw(in byte[] request, out byte[] response, in int sub);
}

View File

@ -0,0 +1,22 @@
/*
* SPDX-FileCopyrightText: 2024 The LineageOS Project
* SPDX-License-Identifier: Apache-2.0
*/
package org.lineageos.motorola.nrenabler
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.util.Log
class BootCompletedReceiver : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
Log.d(TAG, "Starting")
context.startService(Intent(context, NrEnablerService::class.java))
}
companion object {
private const val TAG = "MotoNrEnabler"
}
}

View File

@ -0,0 +1,94 @@
/*
* SPDX-FileCopyrightText: 2024 The LineageOS Project
* SPDX-License-Identifier: Apache-2.0
*/
package org.lineageos.motorola.nrenabler
import android.app.Service
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.os.Handler
import android.os.IBinder
import android.telephony.CarrierConfigManager
import android.telephony.SubscriptionManager
import android.telephony.TelephonyManager
import android.util.Log
import java.util.concurrent.atomic.AtomicBoolean
class NrEnablerService : Service() {
private lateinit var motoExtService: QcomMotoExtTelephonyService
private val handler by lazy { Handler(mainLooper) }
private val workingInProgress = AtomicBoolean(false)
private val repeatWorkOnNRModeAndDSSIfFail = object : Runnable {
override fun run() {
if (workingInProgress.getAndSet(true))
return
if (!workOnNRModeAndDSS()) {
Log.v(TAG, "workOnNRModeAndDSS failed, retry after 5s")
handler.removeCallbacks(this)
handler.postDelayed(this, 5000)
}
workingInProgress.set(false)
}
}
private val broadcastReceiver = object : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
if (!workingInProgress.get()) {
handler.post(repeatWorkOnNRModeAndDSSIfFail)
}
}
}
override fun onCreate() {
motoExtService = QcomMotoExtTelephonyService(this)
registerReceiver(
broadcastReceiver, IntentFilter(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED)
)
}
private fun workOnNRModeAndDSS(): Boolean {
val activeSubs =
getSystemService(SubscriptionManager::class.java)?.getActiveSubscriptionInfoList()
if (activeSubs.isNullOrEmpty()) {
Log.v(TAG, "workOnNRModeAndDSS: no active sub.")
return true
}
for (aSubInfo in activeSubs) {
val phoneId = SubscriptionManager.getPhoneId(aSubInfo.subscriptionId)
if (!validatePhoneId(phoneId)) {
Log.e(TAG, "Invalid phoneId: $phoneId")
return false
}
// Moto sets them based on carrier config, but we unconditionally
// enable NR and DSS here because maintaining carrier config is
// intractable for us.
Log.v(TAG, "workOnNRModeAndDSS: setNrModeDisabled for phone ${phoneId}")
if (!motoExtService.setNrModeDisabled(phoneId, NrMode.AUTO)) {
return false
}
Log.v(TAG, "workOnNRModeAndDSS: setDSSEnabled for phone ${phoneId}")
if (!motoExtService.setDSSEnabled(phoneId, 1.toByte())) {
return false
}
}
return true
}
private fun validatePhoneId(phoneId: Int): Boolean {
val phoneCount =
getSystemService(TelephonyManager::class.java)?.activeModemCount ?: return false
return phoneId in 0 until phoneCount
}
override fun onBind(intent: Intent?): IBinder? = null
companion object {
private const val TAG = "MotoNrEnabler"
}
}

View File

@ -0,0 +1,27 @@
/*
* SPDX-FileCopyrightText: 2024 The LineageOS Project
* SPDX-License-Identifier: Apache-2.0
*/
package org.lineageos.motorola.nrenabler
enum class NrMode(private val id: Int) {
AUTO(0),
DISABLE_SA(1),
DISABLE_NSA(2);
fun toInt(): Int {
return id
}
companion object {
fun fromInt(id: Int): NrMode? {
for (en in NrMode.values()) {
if (en.id == id) {
return en
}
}
return null
}
}
}

View File

@ -0,0 +1,65 @@
/*
* SPDX-FileCopyrightText: 2024 The LineageOS Project
* SPDX-License-Identifier: Apache-2.0
*/
package org.lineageos.motorola.nrenabler
import android.content.Context
import android.util.Log
import com.android.internal.telephony.PhoneFactory
import java.nio.ByteBuffer
class QcomMotoExtTelephonyService(private val context: Context) {
private val qcrilMsgTunnelConnector = QcrilMsgTunnelConnector(context)
fun setNrModeDisabled(phoneId: Int, mode: NrMode): Boolean {
val nrModeInModem = getNrModeDisabled(phoneId)
Log.v(TAG, "nrModeInModem = $nrModeInModem")
if (mode == nrModeInModem) {
Log.d(
TAG,
"setNrModeDisabled equals nrModeInModem:$nrModeInModem, ignore set for phoneID:$phoneId"
)
return true
}
val data = ByteArray(9)
val buf = ByteBuffer.wrap(data)
buf.order(QcomOemConstants.getByteOrderByRequestId(QcomOemConstants.OEM_RIL_REQUEST_SET_NR_DISABLE_MODE))
buf.putInt(QcomOemConstants.OEM_RIL_REQUEST_SET_NR_DISABLE_MODE).putInt(1)
.put(mode.toInt().toByte())
return qcrilMsgTunnelConnector.invokeOemRilRequestRawForPhone(phoneId, data, null) >= 0
}
private fun getNrModeDisabled(phoneId: Int): NrMode? {
val data = ByteArray(8)
val respData = ByteArray(1)
val buf = ByteBuffer.wrap(data)
buf.order(QcomOemConstants.getByteOrderByRequestId(QcomOemConstants.OEM_RIL_REQUEST_GET_NR_DISABLE_MODE))
buf.putInt(QcomOemConstants.OEM_RIL_REQUEST_GET_NR_DISABLE_MODE)
if (qcrilMsgTunnelConnector.invokeOemRilRequestRawForPhone(phoneId, data, respData) >= 0) {
return NrMode.fromInt(respData[0].toInt())
}
return null
}
private fun getDSSEnabled(phoneId: Int): Byte {
val rdeNv =
qcrilMsgTunnelConnector.getRdeNvValueByElementId(phoneId, QcomNvInfo.RDE_EFS_DSS_I)
return (rdeNv?.dataObj as QcomNvInfo.NvGenericDataType?)?.data?.get(0) ?: 2.toByte()
}
fun setDSSEnabled(phoneId: Int, enabled: Byte): Boolean {
val prev = getDSSEnabled(phoneId)
Log.v(TAG, "previous DSS mode = $prev")
if (prev == enabled) {
Log.d(TAG, "Skip setDSSEnabled as no change.")
return true
}
return qcrilMsgTunnelConnector.setRdeNvValue(phoneId, QcomNvInfo.RDE_EFS_DSS_I, enabled)
}
companion object {
private const val TAG = "MotoNrEnabler: QcomMotoExtTelephonyService"
}
}

View File

@ -0,0 +1,65 @@
/*
* SPDX-FileCopyrightText: 2024 The LineageOS Project
* SPDX-License-Identifier: Apache-2.0
*/
package org.lineageos.motorola.nrenabler
import android.util.Log
import java.nio.ByteBuffer
import java.nio.ByteOrder
object QcomNvInfo {
private const val TAG = "MotoNrEnabler: QcomNvInfo"
const val RDE_EFS_DSS_I = 10030
interface NvDataType {
fun serialize(buf: ByteBuffer)
fun size(): Int
}
class RdeNvValue {
var elementId = 0
var recordNum = 0
var offset = 0
var length = 0
var dataObj: NvDataType? = null
val size: Int
get() {
return (dataObj?.size() ?: 1) + 16
}
}
class NvGenericDataType : NvDataType {
var data: ByteArray? = null
constructor()
constructor(byte: Byte) {
data = byteArrayOf(byte)
}
override fun serialize(buf: ByteBuffer) {
data?.let {
buf.put(it)
}
}
override fun size(): Int {
return data?.size ?: 0
}
}
fun getRdeByteOrder(): ByteOrder {
return QcomOemConstants.getByteOrderByRequestId(QcomOemConstants.OEM_RIL_REQUEST_CDMA_GET_RDE_ITEM)
}
fun getRdeNvName(elementId: Int): String {
return when (elementId) {
RDE_EFS_DSS_I -> "RDE_EFS_DSS_I"
else -> {
Log.w(TAG, "unknown RDE element ID: $elementId")
""
}
}
}
}

View File

@ -0,0 +1,217 @@
/*
* SPDX-FileCopyrightText: 2024 The LineageOS Project
* SPDX-License-Identifier: Apache-2.0
*/
package org.lineageos.motorola.nrenabler
import android.util.Log
import java.nio.BufferUnderflowException
import java.nio.ByteBuffer
object QcomNvUtils {
private const val TAG = "MotoNrEnabler: QcomNvUtils"
private const val DEFAULT_SPC_CODE = "000000"
private const val READING_RDE_RESP_BUF_SIZE = 6144
private const val WRITING_RESP_BUF_SIZE = 2048
data class OemHookDataHeader(
val reqId: Int,
val dataLength: Int,
val error: OemHookRespError,
) {
val spcLockCode = ByteArray(6)
override fun toString(): String {
return "reqId = $reqId dataLength = $dataLength error = $error spcLockCode = ${
byteArrToStringLog(
spcLockCode
)
}"
}
companion object {
const val SIZE = 18
}
}
fun readOemHookRespHeader(reqId: Int, bytes: ByteArray?): OemHookDataHeader? {
return bytes?.let {
readOemHookRespHeader(
ByteBuffer.wrap(it).order(QcomOemConstants.getByteOrderByRequestId(reqId))
)
}
}
private fun readOemHookRespHeader(buf: ByteBuffer): OemHookDataHeader? {
return try {
val header = OemHookDataHeader(
buf.getInt(),
buf.getInt(),
OemHookRespError.fromInt(buf.getInt()),
)
for (i in 0 until header.spcLockCode.size) {
header.spcLockCode[i] = buf.get()
}
Log.d(TAG, "readOemHookRespHeader: $header")
header
} catch (e: BufferUnderflowException) {
Log.w(TAG, "decode RespHeader exception, BufferUnderflowException")
null
}
}
fun getReadingRdeNvReqData(rdeNv: QcomNvInfo.RdeNvValue): ByteArray {
return allocateRdeOemReqData(
QcomOemConstants.OEM_RIL_REQUEST_CDMA_GET_RDE_ITEM, rdeNv, DEFAULT_SPC_CODE
)
}
fun getWritingRdeNvReqData(rdeNv: QcomNvInfo.RdeNvValue): ByteArray {
return allocateRdeOemReqData(
QcomOemConstants.OEM_RIL_REQUEST_CDMA_SET_RDE_ITEM, rdeNv, DEFAULT_SPC_CODE
)
}
private fun allocateRdeOemReqData(
reqId: Int, rdeNv: QcomNvInfo.RdeNvValue, spcCode: String
): ByteArray {
val buf = ByteBuffer.allocate(rdeNv.size + OemHookDataHeader.SIZE)
buf.order(QcomNvInfo.getRdeByteOrder())
writeOemHookReqHeader(
buf, reqId, rdeNv.size, OemHookRespError.OEM_RIL_CDMA_SUCCESS, spcCode
)
buf.putInt(rdeNv.elementId)
buf.putInt(rdeNv.recordNum)
buf.putInt(rdeNv.offset)
rdeNv.dataObj.let {
if (it != null) {
buf.putInt(it.size())
it.serialize(buf)
} else {
buf.putInt(0)
buf.put(0.toByte())
}
}
val data = buf.array()
Log.d(
TAG,
"RDE request for element: ${QcomNvInfo.getRdeNvName(rdeNv.elementId)} Allocated OemReqData: data = ${
byteArrToStringLog(
data
)
}"
)
return data
}
fun allocateReadingRdeNvRespBuffer(): ByteArray {
return ByteArray(READING_RDE_RESP_BUF_SIZE)
}
fun allocateWritingRdeNvRespBuffer(): ByteArray {
return ByteArray(WRITING_RESP_BUF_SIZE)
}
fun decodeReadingRdeNvResult(resultData: ByteArray?): QcomNvInfo.RdeNvValue? {
if (resultData == null) {
return null
}
val buf = ByteBuffer.wrap(resultData).order(QcomNvInfo.getRdeByteOrder())
return try {
val header = readOemHookRespHeader(buf)
if (header != null && header.error === OemHookRespError.OEM_RIL_CDMA_SUCCESS) {
return deserializeRde(buf)
}
Log.w(TAG, "decodeReadingRdeNv get error for head")
null
} catch (e: BufferUnderflowException) {
Log.e(TAG, "decodeReadingRdeNvResult: buffer underflow")
null
}
}
private fun deserializeRde(buf: ByteBuffer): QcomNvInfo.RdeNvValue {
val rdeNv = QcomNvInfo.RdeNvValue()
rdeNv.elementId = buf.getInt()
rdeNv.recordNum = buf.getInt()
rdeNv.offset = buf.getInt()
rdeNv.length = buf.getInt()
Log.d(TAG, "decoding response for ${QcomNvInfo.getRdeNvName(rdeNv.elementId)}")
when (rdeNv.elementId) {
QcomNvInfo.RDE_EFS_DSS_I -> {
if (rdeNv.length > 0) {
val nvData = QcomNvInfo.NvGenericDataType()
nvData.data = buf.array().copyOfRange(34, 34 + rdeNv.length)
rdeNv.dataObj = nvData
}
}
else -> Log.d(TAG, "deserialize unknown elementId (${rdeNv.elementId})")
}
return rdeNv
}
fun byteArrToStringLog(arr: ByteArray?): String {
if (arr == null || arr.isEmpty()) {
return "null"
}
val sb = StringBuilder()
for (i in arr) {
sb.append(String.format("%02X", i))
}
return sb.toString()
}
private fun writeOemHookReqHeader(
buf: ByteBuffer, reqId: Int, len: Int, err: OemHookRespError, spcLockCode: String
) {
writeOemHookReqHeader(buf, reqId, len, err, spcLockCode.toByteArray())
}
private fun writeOemHookReqHeader(
buf: ByteBuffer, reqId: Int, len: Int, err: OemHookRespError, spcLockCode: ByteArray
) {
buf.putInt(reqId)
buf.putInt(len)
buf.putInt(err.toInt())
for (i in spcLockCode) {
buf.put(i)
}
Log.d(
TAG,
"writeOemHookReqHeader: reqId = $reqId dataLength = $len error = $err spcLockCode = ${
byteArrToStringLog(
spcLockCode
)
}"
)
}
enum class OemHookRespError(private val id: Int) {
OEM_RIL_CDMA_SUCCESS(0),
OEM_RIL_CDMA_RADIO_NOT_AVAILABLE(1),
OEM_RIL_CDMA_NAM_READ_WRITE_FAILURE(2),
OEM_RIL_CDMA_NAM_PASSWORD_INCORRECT(3),
OEM_RIL_CDMA_NAM_ACCESS_COUNTER_EXCEEDED(4),
OEM_RIL_CDMA_GENERIC_FAILURE(5);
fun toInt(): Int {
return id
}
companion object {
fun fromInt(id: Int): OemHookRespError {
for (en in values()) {
if (en.id == id) {
return en
}
}
return OEM_RIL_CDMA_GENERIC_FAILURE
}
}
}
}

View File

@ -0,0 +1,36 @@
/*
* SPDX-FileCopyrightText: 2024 The LineageOS Project
* SPDX-License-Identifier: Apache-2.0
*/
package org.lineageos.motorola.nrenabler
import android.util.Log
import java.nio.ByteOrder
object QcomOemConstants {
const val TAG = "MotoNrEnabler: QcomOemConstants"
private const val OEM_RIL_CDMA_MESSAGE_TYPE_CDMA = 33554432
const val OEM_RIL_REQUEST_GET_NR_DISABLE_MODE = 327752
const val OEM_RIL_REQUEST_SET_NR_DISABLE_MODE = 327753
const val OEM_RIL_REQUEST_CDMA_SET_RDE_ITEM = 33554453
const val OEM_RIL_REQUEST_CDMA_GET_RDE_ITEM = 33554454
fun getByteOrderByRequestId(reqId: Int): ByteOrder {
return if (reqId >= OEM_RIL_CDMA_MESSAGE_TYPE_CDMA) {
ByteOrder.LITTLE_ENDIAN
} else ByteOrder.BIG_ENDIAN
}
fun getRequestName(reqId: Int): String {
return when (reqId) {
OEM_RIL_REQUEST_CDMA_SET_RDE_ITEM -> "OEM_RIL_REQUEST_CDMA_SET_RDE_ITEM"
OEM_RIL_REQUEST_CDMA_GET_RDE_ITEM -> "OEM_RIL_REQUEST_CDMA_GET_RDE_ITEM"
else -> {
Log.w(TAG, "unknown request ID: $reqId")
""
}
}
}
}

View File

@ -0,0 +1,161 @@
/*
* SPDX-FileCopyrightText: 2024 The LineageOS Project
* SPDX-License-Identifier: Apache-2.0
*/
package org.lineageos.motorola.nrenabler
import android.content.ComponentName
import android.content.Context
import android.content.Intent
import android.content.ServiceConnection
import android.os.Handler
import android.os.IBinder
import android.os.RemoteException
import android.util.Log
import com.android.internal.telephony.uicc.IccUtils
import com.qualcomm.qcrilmsgtunnel.IQcrilMsgTunnel
class QcrilMsgTunnelConnector(private val context: Context) {
private val handler = Handler(context.mainLooper)
private var qcrilMsgService: IQcrilMsgTunnel? = null
private val qcrilMsgTunnelConnection: ServiceConnection = object : ServiceConnection {
override fun onServiceConnected(name: ComponentName, service: IBinder) {
Log.d(TAG, "QcrilMsgTunnel Service connected")
qcrilMsgService = IQcrilMsgTunnel.Stub.asInterface(service)
if (qcrilMsgService == null) {
Log.e(TAG, "QcrilMsgTunnelService Connect Failed (onServiceConnected)")
return
}
service.linkToDeath(qcrilMsgServiceDeathRecipient, 0)
}
override fun onServiceDisconnected(name: ComponentName) {
Log.e(TAG, "The connection to the service got disconnected unexpectedly!")
qcrilMsgService = null
}
}
private val qcrilMsgServiceDeathRecipient = IBinder.DeathRecipient {
Log.e(TAG, "QcrilMsgService Died")
context.unbindService(qcrilMsgTunnelConnection)
handler.postDelayed({ bindToQcrilMsgTunnelService() }, 4000)
}
init {
bindToQcrilMsgTunnelService()
}
private fun bindToQcrilMsgTunnelService() {
val intent = Intent()
intent.setClassName(QCRIL_MSG_TUNNEL_PACKAGE_NAME, QCRIL_MSG_TUNNEL_SERVICE_NAME)
Log.d(TAG, "Starting QcrilMsgTunnel Service")
context.bindService(intent, qcrilMsgTunnelConnection, Context.BIND_AUTO_CREATE)
}
fun invokeOemRilRequestRawForPhone(phoneId: Int, oemReq: ByteArray?, oemResp: ByteArray?): Int {
return qcrilMsgService?.let {
Log.d(
TAG, "invokeOemRilRequestRawForSubscriber: phoneId = $phoneId oemReq = ${
IccUtils.bytesToHexString(
oemReq
)
}"
)
val rspData = oemResp ?: ByteArray(1)
try {
val ret = it.sendOemRilRequestRaw(oemReq, rspData, phoneId)
Log.d(
TAG, "invokeOemRilRequestRawForSubscriber: phoneId = $phoneId oemResp = ${
IccUtils.bytesToHexString(rspData)
}"
)
ret
} catch (e: RemoteException) {
Log.e(TAG, "sendOemRilRequestRaw: Runtime Exception")
-1
}
} ?: run {
Log.e(TAG, "QcrilMsgTunnel Service not connected")
-1
}
}
private fun getRdeNvValueByElementId(
phoneId: Int, rdeElementId: Int, recordNum: Int
): QcomNvInfo.RdeNvValue? {
if (rdeElementId < 0) {
return null
}
val rdeNv = QcomNvInfo.RdeNvValue()
rdeNv.elementId = rdeElementId
rdeNv.recordNum = recordNum
val reqRdeData: ByteArray = QcomNvUtils.getReadingRdeNvReqData(rdeNv)
val respRdeData: ByteArray = QcomNvUtils.allocateReadingRdeNvRespBuffer()
return if (invokeOemRilRequestRawForPhone(
phoneId, reqRdeData, respRdeData
) < 0
) {
null
} else QcomNvUtils.decodeReadingRdeNvResult(respRdeData)
}
fun getRdeNvValueByElementId(phoneId: Int, rdeElementId: Int): QcomNvInfo.RdeNvValue? {
return getRdeNvValueByElementId(phoneId, rdeElementId, 0)
}
fun setRdeNvValue(phoneId: Int, rdeElementId: Int, value: Byte): Boolean {
val data = QcomNvInfo.NvGenericDataType(value)
return setRdeNvValue(phoneId, rdeElementId, data)
}
private fun setRdeNvValue(
phoneId: Int, rdeElementId: Int, nvData: QcomNvInfo.NvDataType
): Boolean {
return setRdeNvValue(phoneId, rdeElementId, 0, nvData)
}
private fun setRdeNvValue(
phoneId: Int, rdeElementId: Int, rdeRecordNum: Int, nvData: QcomNvInfo.NvDataType
): Boolean {
val nv = QcomNvInfo.RdeNvValue()
nv.elementId = rdeElementId
nv.recordNum = rdeRecordNum
nv.dataObj = nvData
return setRdeNvValue(phoneId, nv)
}
private fun setRdeNvValue(phoneId: Int, nv: QcomNvInfo.RdeNvValue): Boolean {
val reqData: ByteArray = QcomNvUtils.getWritingRdeNvReqData(nv)
val respData: ByteArray = QcomNvUtils.allocateWritingRdeNvRespBuffer()
return getWritingRdeNvRespResult(phoneId, reqData, respData)
}
private fun getWritingRdeNvRespResult(
phoneId: Int, reqData: ByteArray, respData: ByteArray
): Boolean {
return getWritingNvRespResult(
phoneId, QcomOemConstants.OEM_RIL_REQUEST_CDMA_SET_RDE_ITEM, reqData, respData
)
}
private fun getWritingNvRespResult(
phoneId: Int, reqId: Int, reqData: ByteArray, respData: ByteArray
): Boolean {
if (invokeOemRilRequestRawForPhone(phoneId, reqData, respData) < 0) {
return false
}
val respHeader = QcomNvUtils.readOemHookRespHeader(reqId, respData) ?: return false
Log.d(
TAG, "get Writing NV result for ${QcomOemConstants.getRequestName(respHeader.reqId)}"
)
return respHeader.error == QcomNvUtils.OemHookRespError.OEM_RIL_CDMA_SUCCESS
}
companion object {
private const val TAG = "MotoNrEnabler: QcrilMsgTunnelConnector"
private const val QCRIL_MSG_TUNNEL_PACKAGE_NAME = "com.qualcomm.qcrilmsgtunnel"
private const val QCRIL_MSG_TUNNEL_SERVICE_NAME =
"com.qualcomm.qcrilmsgtunnel.QcrilMsgTunnelService"
}
}

View File

@ -0,0 +1,4 @@
hidl_package_root {
name: "com.motorola",
path: "hardware/motorola/interfaces/motorola",
}

View File

@ -0,0 +1,3 @@
02b55f97c2a6633f7a9a3f87f1a945028dfb0e6308ecee2856d2f510b5e1e852 com.motorola.hardware.biometric.fingerprint@1.0::types
fc3273905e20cc30ba21c436179a25097f22b4e586244fb772ec2258cbe58504 com.motorola.hardware.biometric.fingerprint@1.0::IMotoFingerPrint
0f24eb5a7ac7b8e6c7bad7997a6fb784c732e967f88ebfc619a57dbc55e8d30c com.motorola.hardware.biometric.fingerprint@1.0::IMotoFingerPrintSensorTest

View File

@ -0,0 +1,15 @@
// This file is autogenerated by hidl-gen -Landroidbp.
hidl_interface {
name: "com.motorola.hardware.biometric.fingerprint@1.0",
root: "com.motorola",
srcs: [
"IMotoFingerPrint.hal",
"IMotoFingerPrintSensorTest.hal",
"types.hal",
],
interfaces: [
"android.hidl.base@1.0",
],
gen_java: true,
}

View File

@ -0,0 +1,23 @@
/*
* Copyright (C) 2022 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.motorola.hardware.biometric.fingerprint@1.0;
interface IMotoFingerPrint {
sendFodEvent(IMotFodEventType eventType, vec<int8_t> eventId) generates (IMotFodEventResult result, vec<int8_t> eventId);
};

View File

@ -0,0 +1,28 @@
/*
* Copyright (C) 2022 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.motorola.hardware.biometric.fingerprint@1.0;
interface IMotoFingerPrintSensorTest {
getSensorInfo();
checkerboardTest();
finishSensorTest(int32_t id);
imagequalityTest();
otpvalidationTest();
selfTest();
};

View File

@ -0,0 +1,31 @@
/*
* Copyright (C) 2022 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.motorola.hardware.biometric.fingerprint@1.0;
enum IMotFodEventType : int32_t {
FINGER_DOWN = 0,
FINGER_UP = 1,
CANCEL = 2,
EXTEND_1 = 3,
EXTEND_2 = 4,
UNKNOWN = 5,
};
enum IMotFodEventResult : int32_t {
RESULT_OK = 0,
RESULT_ERR = 1,
};