From b9c0368d7afa9cbbcc465accffa1ce68e723123c Mon Sep 17 00:00:00 2001 From: Lex Huang Date: Fri, 19 May 2023 15:52:12 +0000 Subject: [PATCH] Fix ActivityNotFoundException Set intent to preference if intent.resolveActivity is non-null Set preference selectable to false if no intent set to preference Fix: 283107867 Test: manual, atest BlockingPrefWithSliceControllerTest Change-Id: Ib5e8705debb5eb5224d8566215cb65f36613d8f9 --- .../BlockingPrefWithSliceController.java | 6 +++-- .../BlockingPrefWithSliceControllerTest.java | 26 ++++++++++++++----- 2 files changed, 23 insertions(+), 9 deletions(-) diff --git a/src/com/android/settings/bluetooth/BlockingPrefWithSliceController.java b/src/com/android/settings/bluetooth/BlockingPrefWithSliceController.java index b443047d7e8..355a9960d07 100644 --- a/src/com/android/settings/bluetooth/BlockingPrefWithSliceController.java +++ b/src/com/android/settings/bluetooth/BlockingPrefWithSliceController.java @@ -59,7 +59,7 @@ import java.util.Optional; * until {@link Slice} is fully loaded. */ public class BlockingPrefWithSliceController extends BasePreferenceController implements - LifecycleObserver, OnStart, OnStop, Observer, BasePreferenceController.UiBlocker{ + LifecycleObserver, OnStart, OnStop, Observer, BasePreferenceController.UiBlocker { private static final String TAG = "BlockingPrefWithSliceController"; private static final String PREFIX_KEY = "slice_preference_item_"; @@ -213,7 +213,8 @@ public class BlockingPrefWithSliceController extends BasePreferenceController im } else { expectedActivityIntent = intentFromSliceAction; } - if (expectedActivityIntent != null) { + if (expectedActivityIntent != null && expectedActivityIntent.resolveActivity( + mContext.getPackageManager()) != null) { Log.d(TAG, "setIntent: ActivityIntent" + expectedActivityIntent); // Since UI needs to support the Settings' 2 panel feature, the intent can't use the // FLAG_ACTIVITY_NEW_TASK. The above intent may have the FLAG_ACTIVITY_NEW_TASK @@ -222,6 +223,7 @@ public class BlockingPrefWithSliceController extends BasePreferenceController im preference.setIntent(expectedActivityIntent); } else { Log.d(TAG, "setIntent: Intent is null"); + preference.setSelectable(false); } } diff --git a/tests/unit/src/com/android/settings/bluetooth/BlockingPrefWithSliceControllerTest.java b/tests/unit/src/com/android/settings/bluetooth/BlockingPrefWithSliceControllerTest.java index 65b6977116d..d5a2585b11e 100644 --- a/tests/unit/src/com/android/settings/bluetooth/BlockingPrefWithSliceControllerTest.java +++ b/tests/unit/src/com/android/settings/bluetooth/BlockingPrefWithSliceControllerTest.java @@ -16,6 +16,8 @@ package com.android.settings.bluetooth; +import static androidx.slice.builders.ListBuilder.ICON_IMAGE; + import static com.google.common.truth.Truth.assertThat; import static org.mockito.ArgumentMatchers.any; @@ -24,8 +26,8 @@ import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; import android.app.PendingIntent; -import android.content.Context; import android.content.ContentResolver; +import android.content.Context; import android.content.Intent; import android.net.Uri; @@ -42,20 +44,20 @@ import androidx.test.annotation.UiThreadTest; import androidx.test.core.app.ApplicationProvider; import androidx.test.ext.junit.runners.AndroidJUnit4; -import com.android.settings.bluetooth.BlockingPrefWithSliceController; - import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; +import org.mockito.ArgumentCaptor; +import org.mockito.Captor; import org.mockito.Mock; -import org.mockito.MockitoAnnotations; import org.mockito.junit.MockitoJUnit; import org.mockito.junit.MockitoRule; +@RunWith(AndroidJUnit4.class) public class BlockingPrefWithSliceControllerTest { private static final String KEY = "bt_device_slice_category"; - private static final String TEST_URI_AUTHORITY = "com.android.authority.test"; + private static final String TEST_URI_AUTHORITY = "com.android.settings"; private static final String TEST_EXTRA_INTENT = "EXTRA_INTENT"; private static final String TEST_EXTRA_PENDING_INTENT = "EXTRA_PENDING_INTENT"; private static final String TEST_INTENT_ACTION = "test"; @@ -71,6 +73,8 @@ public class BlockingPrefWithSliceControllerTest { private LiveData mLiveData; @Mock private PreferenceCategory mPreferenceCategory; + @Captor + ArgumentCaptor mPreferenceArgumentCaptor; private Context mContext; private BlockingPrefWithSliceController mController; @@ -130,6 +134,14 @@ public class BlockingPrefWithSliceControllerTest { verify(mController.mPreferenceCategory).addPreference(any()); } + @Test + public void onChanged_sliceWithoutValidIntent_makePreferenceUnselectable() { + mController.onChanged(buildTestSlice()); + + verify(mController.mPreferenceCategory).addPreference(mPreferenceArgumentCaptor.capture()); + assertThat(mPreferenceArgumentCaptor.getValue().isSelectable()).isFalse(); + } + private Slice buildTestSlice() { Uri uri = new Uri.Builder() @@ -141,7 +153,7 @@ public class BlockingPrefWithSliceControllerTest { IconCompat icon = mock(IconCompat.class); listBuilder.addRow( new RowBuilder() - .setTitleItem(icon, ListBuilder.ICON_IMAGE) + .setTitleItem(icon, ICON_IMAGE) .setTitle(TEST_SLICE_TITLE) .setSubtitle(TEST_SLICE_SUBTITLE) .setPrimaryAction( @@ -153,7 +165,7 @@ public class BlockingPrefWithSliceControllerTest { PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE), icon, - ListBuilder.ICON_IMAGE, + ICON_IMAGE, ""))); return listBuilder.build(); }