mirror of
https://github.com/saphid/frame-control.git
synced 2026-10-06 02:00:19 +02:00
Patch the activity the launcher alias targets, not the first MAIN filter
Second review follow-up: with several activities (e.g. a splash activity ahead of the game), the alias fallback now prefers the real activity named by the alias's android:targetActivity. Reads targetActivity by resource id, updates the error text and docs/vr-apks.md. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
268afccf05
commit
9e9e5950d0
5 files changed
+37
-10
No files matched your search
+1
-1
@@ -322,7 +322,7 @@ def patch(src, dst, add=None):
|
||||
original = frame_apk._read(z, 'AndroidManifest.xml', frame_apk.MAX_MANIFEST)
|
||||
manifest = add_launcher_category(original) if info['repairable'] else original
|
||||
if not info['launchable'] and not info['repairable']:
|
||||
raise FrameError('APK has no MAIN/LAUNCHER or patchable VR activity')
|
||||
raise FrameError('APK has no MAIN/LAUNCHER activity that Frame Control can patch')
|
||||
repack(src, dst, replace={'AndroidManifest.xml': manifest}, add=add)
|
||||
result = apk_info(dst)
|
||||
result.pop('icon_png', None)
|
||||
|
||||
+2
-1
@@ -10,7 +10,8 @@ import zipfile
|
||||
|
||||
# android: attribute resource ids; names can be stripped by shrinkers, ids can't.
|
||||
ATTR = {0x01010001: 'label', 0x01010002: 'icon', 0x01010003: 'name',
|
||||
0x01010024: 'value', 0x0101021b: 'versionCode', 0x0101021c: 'versionName', 0x0101020c: 'minSdkVersion'}
|
||||
0x01010024: 'value', 0x0101021b: 'versionCode', 0x0101021c: 'versionName', 0x0101020c: 'minSdkVersion',
|
||||
0x01010202: 'targetActivity'}
|
||||
T_REF, T_STRING, T_INT_DEC, T_INT_HEX = 0x01, 0x03, 0x10, 0x11
|
||||
# APKs can come from websites (install links), so nothing read from one may be
|
||||
# unbounded. zipfile stops at a member's declared size, so checking it is enough.
|
||||
|
||||
+9
-2
@@ -10,13 +10,18 @@ VR = {'com.oculus.intent.category.VR', 'org.khronos.openxr.intent.category.IMMER
|
||||
def inspect(data):
|
||||
elements = iter(frame_apk.manifest_elements(data))
|
||||
stack, filters, samsung = [], [], False
|
||||
current = None
|
||||
current, owner, package = None, None, ''
|
||||
for kind, hs, off, size in frame_apk._chunks(data, 8, len(data)):
|
||||
if kind == 0x0102:
|
||||
tag, attrs = next(elements)
|
||||
value = attrs.get('name', (None, None, None))[2]
|
||||
if tag == 'manifest':
|
||||
package = attrs.get('package', (None, None, None))[2] or ''
|
||||
if tag in ('activity', 'activity-alias'):
|
||||
owner = attrs.get('targetActivity', (None, None, None))[2] if tag == 'activity-alias' else value
|
||||
owner = package + owner if owner and owner.startswith('.') else owner
|
||||
if tag == 'intent-filter' and stack and stack[-1] in ('activity', 'activity-alias'):
|
||||
current = {'actions': set(), 'categories': set(), 'templates': [], 'alias': stack[-1] == 'activity-alias'}
|
||||
current = {'actions': set(), 'categories': set(), 'templates': [], 'alias': stack[-1] == 'activity-alias', 'activity': owner}
|
||||
if current is not None and stack and stack[-1] == 'intent-filter':
|
||||
if tag == 'action':
|
||||
current['actions'].add(value)
|
||||
@@ -38,7 +43,9 @@ def inspect(data):
|
||||
real = [f for f in mains if not f['alias']]
|
||||
targets = [f for f in real if VR & f['categories']]
|
||||
if not targets and any(LAUNCHER in f['categories'] or VR & f['categories'] for f in mains if f['alias']):
|
||||
aimed = {f['activity'] for f in mains if f['alias'] and (LAUNCHER in f['categories'] or VR & f['categories'])}
|
||||
targets = [f for f in real if f['templates']] # the patch copies an existing <category>
|
||||
targets = [f for f in targets if f['activity'] in aimed] or targets
|
||||
launchable = any(LAUNCHER in f['categories'] for f in real)
|
||||
return {'launchable': launchable, 'repairable': not launchable and bool(targets),
|
||||
'vr_activity': bool(vr_filters), 'vr': bool(vr_filters) or samsung}, targets
|
||||
|
||||
Reference in new issue
Block a user