Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c2291997 authored by Ming-Shin Lu's avatar Ming-Shin Lu
Browse files

Fix a potential crash when calling RingtoneManager#hasHapticChannels

In case the cached context or the input context object in
RingtoneManager which the context object is created by
contextContextByUser that using negative specialized
UserHandle.USER_CURRENT as CL[1] that caused calling
AudioManager#hasHapticChannelsImpl(context, uri) end up
throwing exception when getting the content provider by resolving
negtive user id from the input context.getUserId()

Fix this issue by using the current userId to create user context
to avoid the exception.

[1]: I4f45f9b12b1ae583ab153d6d0025ee7a215a9b81

Bug: 441570690
Flag: EXEMPT BUGFIX
Test: atest AudioManagerTest
Change-Id: Ie768290f7d8c08f61949050587065603e387a87f
parent bdd2d660
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -8961,6 +8961,13 @@ public class AudioManager {
     */
    public static boolean hasHapticChannelsImpl(@NonNull Context context, @NonNull Uri uri) {
        MediaExtractor extractor = new MediaExtractor();
        if (context.getUserId() == UserHandle.USER_CURRENT) {
            // Use the current userId to create user context to avoid the exception thrown
            // during getting content provider accessing non-positive specialized user ID
            // (USER_CURRENT) through context.getUserId().
            context = context.createContextAsUser(
                    UserHandle.of(UserHandle.myUserId()), 0);
        }
        try {
            extractor.setDataSource(context, uri, null);
            for (int i = 0; i < extractor.getTrackCount(); i++) {
+16 −0
Original line number Diff line number Diff line
@@ -36,6 +36,7 @@ import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertThrows;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;

import android.content.Context;
import android.media.AudioAttributes;
@@ -44,8 +45,10 @@ import android.media.AudioSystem;
import android.media.IAudioService;
import android.media.audiopolicy.AudioProductStrategy;
import android.media.audiopolicy.AudioVolumeGroup;
import android.net.Uri;
import android.os.IBinder;
import android.os.ServiceManager;
import android.os.UserHandle;
import android.platform.test.annotations.Presubmit;
import android.util.Log;

@@ -66,6 +69,8 @@ public class AudioManagerTest {
    private static final String TAG = "AudioManagerTest";

    private AudioManager mAudioManager;
    private static final Uri DEFAULT_RINGTONE_URI =
            Uri.parse("content://media/internal/audio/media/10?title=DefaultRingtone&canonical=1");

    private static final int[] PUBLIC_STREAM_TYPES = {
            STREAM_VOICE_CALL,
@@ -409,4 +414,15 @@ public class AudioManagerTest {
            mAudioManager.unregisterVolumeGroupCallback(vgCbReceiver);
        }
    }

    @Test
    public void testHasHapticsChannels_NoException() {
        Context textContext = getApplicationContext().createContextAsUser(UserHandle.CURRENT, 0);
        mAudioManager = textContext.getSystemService(AudioManager.class);
        try {
            AudioManager.hasHapticChannels(null, DEFAULT_RINGTONE_URI);
        } catch (Exception e) {
            fail("testHasHapticsChannels fails with an exception: " + e);
        }
    }
}