Skip to content

Commit 6f302c3

Browse files
committed
sebaubuntu_libs: libandroid: partitions: Import from aospdtgen
Change-Id: Ia79b408e40946227f644fabb9562c34b163c9a4b
1 parent 622c686 commit 6f302c3

4 files changed

Lines changed: 238 additions & 0 deletions

File tree

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
#
2+
# Copyright (C) 2022 Sebastiano Barezzi
3+
#
4+
# SPDX-License-Identifier: Apache-2.0
5+
#
6+
"""AOSP partitions library."""
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
#
2+
# Copyright (C) 2022 Sebastiano Barezzi
3+
#
4+
# SPDX-License-Identifier: Apache-2.0
5+
#
6+
7+
from __future__ import annotations
8+
from pathlib import Path
9+
from typing import List
10+
11+
from sebaubuntu_libs.libandroid.fstab import Fstab, FstabEntry
12+
from sebaubuntu_libs.libandroid.partitions.partition_model import PartitionModel
13+
from sebaubuntu_libs.libandroid.props import BuildProp
14+
from sebaubuntu_libs.libandroid.vintf.manifest import Manifest
15+
from sebaubuntu_libs.libpath import is_relative_to
16+
from sebaubuntu_libs.libreorder import strcoll_files_key
17+
18+
BUILD_PROP_LOCATION = ["build.prop", "etc/build.prop"]
19+
DEFAULT_PROP_LOCATION = ["default.prop", "etc/default.prop"]
20+
21+
def get_dir(path: Path):
22+
dir = {}
23+
for i in path.iterdir():
24+
dir[i.name] = i if i.is_file() else get_dir(i)
25+
return dir
26+
27+
class AndroidPartition:
28+
def __init__(self, model: PartitionModel, real_path: Path, dump_path: Path):
29+
self.model = model
30+
self.real_path = real_path
31+
self.dump_path = dump_path
32+
33+
self.files: List[Path] = []
34+
self.fstab_entry: FstabEntry = None
35+
36+
self.build_prop = BuildProp()
37+
for possible_paths in BUILD_PROP_LOCATION + DEFAULT_PROP_LOCATION:
38+
build_prop_path = self.real_path / possible_paths
39+
if not build_prop_path.is_file():
40+
continue
41+
42+
self.build_prop.import_props(build_prop_path)
43+
44+
self.manifest = Manifest()
45+
for possible_paths in ["etc/vintf/manifest.xml", "manifest.xml"]:
46+
manifest_path = self.real_path / possible_paths
47+
if not manifest_path.is_file():
48+
continue
49+
50+
self.manifest.import_file(manifest_path)
51+
52+
def get_relative_path(self):
53+
return self.real_path.relative_to(self.dump_path)
54+
55+
def fill_files(self, files: List[Path]):
56+
for file in files:
57+
if not is_relative_to(file, self.real_path):
58+
continue
59+
60+
self.files.append(file)
61+
62+
def fill_fstab_entry(self, fstab: Fstab):
63+
for mount_point in self.model.mount_points:
64+
self.fstab_entry = fstab.get_partition_by_mount_point(mount_point)
65+
if self.fstab_entry is not None:
66+
return
67+
68+
def get_files(self):
69+
"""Returns the ordered list of files."""
70+
self.files.sort(key=strcoll_files_key)
71+
return self.files
72+
73+
def get_formatted_file(self, file: Path):
74+
return self.model.proprietary_files_prefix / file.relative_to(self.real_path)
75+
76+
def get_formatted_files(self):
77+
return [self.get_formatted_file(file) for file in self.get_files()]
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
#
2+
# Copyright (C) 2022 Sebastiano Barezzi
3+
#
4+
# SPDX-License-Identifier: Apache-2.0
5+
#
6+
7+
from __future__ import annotations
8+
from pathlib import Path
9+
from typing import List
10+
11+
(
12+
BOOTLOADER,
13+
SSI,
14+
TREBLE,
15+
DATA,
16+
) = range(4)
17+
18+
class _PartitionModel:
19+
ALL: List[_PartitionModel] = []
20+
21+
def __init__(self,
22+
name: str,
23+
group: int,
24+
mount_points: List[str] = None,
25+
proprietary_files_prefix: Path = None,
26+
):
27+
self.name = name
28+
self.group = group
29+
self.mount_points = mount_points
30+
self.proprietary_files_prefix = proprietary_files_prefix
31+
32+
if self.mount_points is None:
33+
self.mount_points = [f"/{self.name}"]
34+
35+
if self.proprietary_files_prefix is None:
36+
self.proprietary_files_prefix = Path(self.name)
37+
38+
_PartitionModel.ALL.append(self)
39+
40+
@classmethod
41+
def from_name(cls, name: str):
42+
for model in cls.ALL:
43+
if model.name == name:
44+
return model
45+
46+
return None
47+
48+
@classmethod
49+
def from_group(cls, group: int):
50+
return [model for model in cls.ALL if model.group == group]
51+
52+
@classmethod
53+
def from_mount_point(cls, mount_point: str):
54+
for model in cls.ALL:
55+
if mount_point in model.mount_points:
56+
return model
57+
58+
return None
59+
60+
class PartitionModel(_PartitionModel):
61+
BOOT = _PartitionModel("boot", BOOTLOADER)
62+
DTBO = _PartitionModel("dtbo", BOOTLOADER)
63+
RECOVERY = _PartitionModel("recovery", BOOTLOADER)
64+
MISC = _PartitionModel("misc", BOOTLOADER)
65+
VBMETA = _PartitionModel("vbmeta", BOOTLOADER)
66+
VBMETA_SYSTEM = _PartitionModel("vbmeta_system", BOOTLOADER)
67+
VBMETA_VENDOR = _PartitionModel("vbmeta_vendor", BOOTLOADER)
68+
69+
SYSTEM = _PartitionModel("system", SSI, ["/system", "/"], Path(""))
70+
PRODUCT = _PartitionModel("product", SSI)
71+
SYSTEM_EXT = _PartitionModel("system_ext", SSI)
72+
73+
VENDOR = _PartitionModel("vendor", TREBLE)
74+
ODM = _PartitionModel("odm", TREBLE)
75+
ODM_DLKM = _PartitionModel("odm_dlkm", TREBLE)
76+
VENDOR_DLKM = _PartitionModel("vendor_dlkm", TREBLE)
77+
78+
USERDATA = _PartitionModel("data", DATA)
79+
CACHE = _PartitionModel("cache", DATA)
80+
METADATA = _PartitionModel("metadata", DATA)
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
#
2+
# Copyright (C) 2022 Sebastiano Barezzi
3+
#
4+
# SPDX-License-Identifier: Apache-2.0
5+
#
6+
7+
from pathlib import Path
8+
from typing import Dict
9+
10+
from sebaubuntu_libs.libandroid.partitions.partition import AndroidPartition, BUILD_PROP_LOCATION
11+
from sebaubuntu_libs.libandroid.partitions.partition_model import SSI, TREBLE, PartitionModel
12+
13+
class Partitions:
14+
def __init__(self, dump_path: Path):
15+
self.dump_path = dump_path
16+
17+
self.partitions: Dict[PartitionModel, AndroidPartition] = {}
18+
19+
# Search for system
20+
for system in [self.dump_path / "system", self.dump_path / "system/system"]:
21+
for build_prop_location in BUILD_PROP_LOCATION:
22+
if not (system / build_prop_location).is_file():
23+
continue
24+
25+
self.partitions[PartitionModel.SYSTEM] = AndroidPartition(PartitionModel.SYSTEM, system, self.dump_path)
26+
27+
assert PartitionModel.SYSTEM in self.partitions
28+
self.system = self.partitions[PartitionModel.SYSTEM]
29+
30+
# Search for vendor
31+
for vendor in [self.partitions[PartitionModel.SYSTEM].real_path / "vendor", self.dump_path / "vendor"]:
32+
for build_prop_location in BUILD_PROP_LOCATION:
33+
if not (vendor / build_prop_location).is_file():
34+
continue
35+
36+
self.partitions[PartitionModel.VENDOR] = AndroidPartition(PartitionModel.VENDOR, vendor, self.dump_path)
37+
38+
assert PartitionModel.VENDOR in self.partitions
39+
self.vendor = self.partitions[PartitionModel.VENDOR]
40+
41+
# Search for the other partitions
42+
for model in [model for model in PartitionModel.from_group(SSI) if not (model is PartitionModel.SYSTEM)]:
43+
self._search_for_partition(model)
44+
45+
for model in [model for model in PartitionModel.from_group(TREBLE) if not (model is PartitionModel.VENDOR)]:
46+
self._search_for_partition(model)
47+
48+
def get_partition(self, model: PartitionModel):
49+
if not model:
50+
return None
51+
52+
if model in self.partitions:
53+
return self.partitions[model]
54+
55+
return None
56+
57+
def get_partition_by_name(self, name: str):
58+
return self.get_partition(PartitionModel.from_name(name))
59+
60+
def get_all_partitions(self):
61+
return self.partitions.values()
62+
63+
def _search_for_partition(self, model: PartitionModel):
64+
possible_locations = [
65+
self.partitions[PartitionModel.SYSTEM].real_path / model.name,
66+
self.partitions[PartitionModel.VENDOR].real_path / model.name,
67+
self.dump_path / model.name
68+
]
69+
70+
for location in possible_locations:
71+
for build_prop_location in BUILD_PROP_LOCATION:
72+
if not (location / build_prop_location).is_file():
73+
continue
74+
75+
self.partitions[model] = AndroidPartition(model, location, self.dump_path)

0 commit comments

Comments
 (0)