hrydgard / ppsspp

A PSP emulator for Android, Windows, Mac and Linux, written in C++. Want to contribute? Join us on Discord at https://discord.gg/5NJB6dD or just send pull requests / issues. For discussion use the forums at forums.ppsspp.org.
https://www.ppsspp.org
Other
11.4k stars 2.19k forks source link

org.ppsspp.ppsspp.NativeActivity.packResultCode() IllegalArgumentException #19620

Closed android-1995 closed 1 week ago

android-1995 commented 1 week ago

Game or games this happens in

None

What area of the game / PPSSPP

None

What should happen

    static int packResultCode(int requestCode, int requestId) {
        return (requestCode << 16) | (requestId & 0xFFFF);
    }
    static void checkForValidRequestCode(int requestCode) {
            if ((requestCode & 0xffff0000) != 0) {
                    throw new IllegalArgumentException("Can only use lower 16 bits for requestCode");
            }
        }

Logs

No response

Platform

Android

Mobile device model or graphics card (GPU)

None

PPSSPP version affected

1.18.1

Last working version

No response

Graphics backend (3D API)

Vulkan

Checklist

hrydgard commented 1 week ago

Sorry, I don't understand what the issue here is? What's the actual problem?

android-1995 commented 1 week ago

Sorry, my English is not good. Here is my explanation using AI:

In the code you provided, the packResultCode method is used to pack requestCode and requestId into a single integer, while the checkForValidRequestCode method is used to check if a given requestCode only uses the lower 16 bits of an integer.

First, let's analyze the packResultCode method:

static int packResultCode(int requestCode, int requestId) {
    return (requestCode << 16) | (requestId & 0xFFFF);
}

This method shifts requestCode left by 16 bits and then performs a bitwise AND operation on requestId with 0xFFFF to ensure it only occupies the lowest 16 bits. Finally, it combines these two parts into a new integer through a bitwise OR operation. Since requestCode is shifted left by 16 bits, it actually occupies the highest 16 bits of the new integer, while requestId occupies the lowest 16 bits.

Next, let's analyze the checkForValidRequestCode method:

static void checkForValidRequestCode(int requestCode) {
    if ((requestCode & 0xffff0000) != 0) {
        throw new IllegalArgumentException("Can only use lower 16 bits for requestCode");
    }
}

This method checks if the highest 16 bits of requestCode are all 0. It does this by performing a bitwise AND operation with 0xffff0000. If the result is not 0, it means that at least one bit in the highest 16 bits of requestCode is 1, which violates the rule that only the lower 16 bits can be used. Therefore, the method throws an IllegalArgumentException exception.

However, there is an important issue here:

This means that you cannot directly use the packed value generated by the packResultCode method as the request code for startActivityForResult because it violates Android's restrictions on request codes.

To solve this problem, you should:

  1. Not use packed request codes: Pass requestCode and requestId separately (but note that startActivityForResult only accepts one request code, so you may need to store requestId elsewhere, such as in the extras of an Intent).

  2. Modify the packing logic: If you really need to store these two values in the same integer and unpack them at a later point, you should ensure that your unpacking logic can handle this situation correctly and do not try to use the packed value as the request code for startActivityForResult.

  3. Use other mechanisms: Consider using other mechanisms to pass requestId, such as through the extras of an Intent, global variables, a database, shared preferences, etc.

In summary, you should avoid using the packed value generated by the packResultCode method as the request code for startActivityForResult because it will cause an IllegalArgumentException exception.

Sorry, I don't understand what the issue here is? What's the actual problem?

hrydgard commented 1 week ago

This is still nonsense to me, as checkForValidRequestCode is not a function that exists in the code base. And why anything would care what the upper 16 bits are eludes me.

Did this cause a crash?

android-1995 commented 1 week ago

I'm sorry. I made a mistake, the function is running normally.