"""Binary-manifest VR inspection and minimal launcher repair (stdlib only).""" import struct import frame_apk MAIN = 'android.intent.action.MAIN' LAUNCHER = 'android.intent.category.LAUNCHER' VR = {'com.oculus.intent.category.VR', 'org.khronos.openxr.intent.category.IMMERSIVE_HMD'} def inspect(data): elements = iter(frame_apk.manifest_elements(data)) stack, filters, samsung = [], [], False current = 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 == 'intent-filter' and stack and stack[-1] in ('activity', 'activity-alias'): current = {'actions': set(), 'categories': set(), 'templates': [], 'alias': stack[-1] == 'activity-alias'} if current is not None and stack and stack[-1] == 'intent-filter': if tag == 'action': current['actions'].add(value) if tag == 'category': current['categories'].add(value) current['templates'].append((off, size, hs)) if tag == 'meta-data' and stack and stack[-1] == 'application': samsung |= value == 'com.samsung.android.vr.application.mode' and attrs.get('value', (0, 0, None))[2] == 'vr_only' stack.append(tag) elif kind == 0x0103 and stack: tag = stack.pop() if tag == 'intent-filter' and current is not None: current['end'] = off filters.append(current) current = None mains = [f for f in filters if MAIN in f['actions']] vr_filters = [f for f in mains if VR & f['categories']] # Lepton's apk-info-extractor ignores ; Godot 4 puts LAUNCHER only there. return {'launchable': any(LAUNCHER in f['categories'] for f in mains if not f['alias']), 'vr_activity': bool(vr_filters), 'vr': bool(vr_filters) or samsung}, \ [f for f in vr_filters if not f['alias']] def _append_string(chunk, text): _, hs, size, count, styles, flags, start, style_start = struct.unpack_from('