from pathlib import Path import unittest from lihont.axml import Axml from lihont.manifest import ManifestError, add_activity, has_activity class ManifestActivityTest(unittest.TestCase): @classmethod def setUpClass(cls): cls.apk = Path('OriginalAPKtiktok/com.zhiliaoapp.musically_47.1.3-2024701030_minAPI23(arm64-v8a)(nodpi)_apkmirror.com.apk') if not cls.apk.exists(): raise unittest.SkipTest('clean TikTok base APK is not available') def _manifest(self): from lihont.apkzip import Apk apk = Apk(str(self.apk)) try: return Axml.parse(apk.read('AndroidManifest.xml')) finally: apk.close() def test_private_settings_activity_is_non_exported(self): xml = self._manifest() name = 'lihont.two.settings.LihonTSettingsActivity' add_activity(xml, name, 'LihonT', 0x7F120364) self.assertTrue(has_activity(xml, name)) node = next(n for n in xml.elements('activity') if xml.attr_string(n, 'name') == name) exported = xml.attr(node, 'exported') self.assertIsNotNone(exported) self.assertEqual(0, exported.data) self.assertEqual(0x7F120364, xml.attr(node, 'theme').data) # A second parse verifies the binary XML remains valid after appending # framework attributes and a private activity subtree. reparsed = Axml.parse(xml.build()) self.assertTrue(has_activity(reparsed, name)) def test_launcher_activity_must_explicitly_be_exported(self): xml = self._manifest() with self.assertRaises(ManifestError): add_activity(xml, 'lihont.two.TestLauncher', 'LihonT', 0x7F120364, affinity='lihont.test', launcher=True) if __name__ == '__main__': unittest.main()