defmodule GitGud.Packages.Fdroid.ApkIconTest do
@moduledoc """
Pulling the launcher icon and the app's name out of an APK.
The case that motivated all of this: a release build. R8 rewrites
`res/mipmap-xxxhdpi/ic_launcher.png` to `res/hi.png`, so the only
route from `android:icon` to an image runs through `resources.arsc`.
The convention that came before it still has to work for a debug
build, which is the other half of these tests.
"""
use ExUnit.Case, async: true
alias GitGud.ApkFixtures
alias GitGud.Packages.Formats.Fdroid.Apk
alias GitGud.Packages.Formats.Fdroid.Manifest
@icon_ref 0x7F010000
@label_ref 0x7F020000
@png <<0x89, "PNG", 0x0D, 0x0A, 0x1A, 0x0A>> <> :binary.copy(<<7>>, 64)
defp shrunk, do: ApkFixtures.resource_shrunk_apk(@icon_ref, @label_ref, @png)
describe "a resource-shrunk APK" do
test "resolves the icon through the resource table" do
assert {:ok, @png, "png"} = Apk.icon(shrunk())
end
test "never returns the adaptive-icon XML" do
# `res/ad.xml` is the highest-priority configuration in the table
# (anydpi) and the one thing an index cannot serve.
assert {:ok, bytes, _ext} = Apk.icon(shrunk())
refute bytes == "<adaptive-icon/>, which is not servable"
end
test "reads the label the manifest points at" do
assert {:ok, manifest} = Manifest.parse(ApkFixtures.manifest(@icon_ref, @label_ref))
assert manifest.icon_ref == @icon_ref
assert manifest.label == @label_ref
end
test "has no icon when the table doesn't define the id the manifest names" do
# A manifest pointing at 0x7F990000 over a table that defines
# 0x7F010000: nothing to resolve, and no conventional path to fall
# back to either.
{:ok, {_name, apk}} =
:zip.create(
~c"mismatched.apk",
[
{~c"AndroidManifest.xml", ApkFixtures.manifest(0x7F990000, @label_ref)},
{~c"resources.arsc", ApkFixtures.resources_arsc(@icon_ref, @label_ref)},
{~c"res/hi.png", @png}
],
[:memory]
)
assert Apk.icon(apk) == :none
end
end
describe "an APK whose resource table can't be read" do
test "falls back to the conventional path" do
{:ok, {_name, apk}} =
:zip.create(
~c"debug.apk",
[
{~c"AndroidManifest.xml", ApkFixtures.manifest(@icon_ref, @label_ref)},
{~c"resources.arsc", "not a resource table"},
{~c"res/mipmap-xxxhdpi-v4/ic_launcher.png", @png},
{~c"res/mipmap-mdpi-v4/ic_launcher.png", "low density, should lose"}
],
[:memory]
)
assert {:ok, @png, "png"} = Apk.icon(apk)
end
test "reports no icon rather than a wrong one" do
{:ok, {_name, apk}} =
:zip.create(
~c"bare.apk",
[{~c"AndroidManifest.xml", ApkFixtures.manifest(@icon_ref, @label_ref)}],
[:memory]
)
assert Apk.icon(apk) == :none
end
test "skips a candidate that isn't an image" do
{:ok, {_name, apk}} =
:zip.create(
~c"lying.apk",
[
{~c"AndroidManifest.xml", ApkFixtures.manifest(@icon_ref, @label_ref)},
{~c"res/mipmap-xxxhdpi-v4/ic_launcher.png", "text pretending to be a PNG"}
],
[:memory]
)
assert Apk.icon(apk) == :none
end
end
end
neiam
/gitgud
Git Gud
public · Issues · Pulls · Labels · Forks · Compare · Actions success · Badges · Packages
⭐
1
Log in to mark this repository.
3.3 KiB · text
History
b868907