From 898d6b4d73f40b08a91f69dbdf3b67550f1df198 Mon Sep 17 00:00:00 2001 From: Edgar Wang Date: Mon, 23 Mar 2020 21:04:22 +0800 Subject: [PATCH 1/7] Don't write user_switcher_enabled value when enter this Settings Settings side should not set user_switcher_enabled value when user just visit settings. It will force enable user_switcher_enabled without user confirm. Bug: 141372193 Test: manual & robotest Change-Id: I1bbe166a45837919cbc22a7c42e72251e64cc67f --- .../android/settings/users/MultiUserSwitchBarController.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/com/android/settings/users/MultiUserSwitchBarController.java b/src/com/android/settings/users/MultiUserSwitchBarController.java index a5fdf9b3279..58de14963fa 100644 --- a/src/com/android/settings/users/MultiUserSwitchBarController.java +++ b/src/com/android/settings/users/MultiUserSwitchBarController.java @@ -52,8 +52,6 @@ public class MultiUserSwitchBarController implements SwitchWidgetController.OnSw mListener = listener; mUserCapabilities = UserCapabilities.create(context); mSwitchBar.setChecked(mUserCapabilities.mUserSwitcherEnabled); - Settings.Global.putInt(mContext.getContentResolver(), - Settings.Global.USER_SWITCHER_ENABLED, mSwitchBar.isChecked() ? 1 : 0); if (mUserCapabilities.mDisallowSwitchUser) { mSwitchBar.setDisabledByAdmin(RestrictedLockUtilsInternal From b7e1ececead371a233e615560fb3fbb86373ed75 Mon Sep 17 00:00:00 2001 From: Yanting Yang Date: Fri, 10 Apr 2020 20:08:38 +0800 Subject: [PATCH 2/7] Fix breadcrumb of search results provided by Settings 1. Settings Search need Settings to provide custom site map pairs to build up full breadcrumb for the search results from below pages. - PowerUsageAdvanced - RecentLocationRequestSeeAllFragment - UsbDetailsFragment - UserBackupSettingsActivity 2. Update the screen title of Backup raw index data from Settings to Backup to display correct breadcrumb in Settings Search. Bug: 147851992 Bug: 151206664 Fixes: 152368059 Test: visual and robotests Change-Id: Iaebab8d549bba6be7623708f9833349654e7f2a7 --- .../backup/UserBackupSettingsActivity.java | 4 +-- .../search/CustomSiteMapRegistry.java | 15 ++++++++ .../search/CustomSiteMapRegistryTest.java | 35 +++++++++++++++++++ 3 files changed, 52 insertions(+), 2 deletions(-) diff --git a/src/com/android/settings/backup/UserBackupSettingsActivity.java b/src/com/android/settings/backup/UserBackupSettingsActivity.java index 08461ad787a..e6d313c61ca 100644 --- a/src/com/android/settings/backup/UserBackupSettingsActivity.java +++ b/src/com/android/settings/backup/UserBackupSettingsActivity.java @@ -29,8 +29,8 @@ import androidx.fragment.app.FragmentManager; import com.android.settings.R; import com.android.settings.search.BaseSearchIndexProvider; import com.android.settingslib.search.Indexable; -import com.android.settingslib.search.SearchIndexableRaw; import com.android.settingslib.search.SearchIndexable; +import com.android.settingslib.search.SearchIndexableRaw; import java.util.ArrayList; import java.util.List; @@ -109,7 +109,7 @@ public class UserBackupSettingsActivity extends FragmentActivity implements Inde // Add the activity title SearchIndexableRaw data = new SearchIndexableRaw(context); data.title = context.getString(R.string.privacy_settings_title); - data.screenTitle = context.getString(R.string.settings_label); + data.screenTitle = context.getString(R.string.privacy_settings_title); data.keywords = context.getString(R.string.keywords_backup); data.intentTargetPackage = context.getPackageName(); data.intentTargetClass = UserBackupSettingsActivity.class.getName(); diff --git a/src/com/android/settings/search/CustomSiteMapRegistry.java b/src/com/android/settings/search/CustomSiteMapRegistry.java index 300cf17211d..756479b2495 100644 --- a/src/com/android/settings/search/CustomSiteMapRegistry.java +++ b/src/com/android/settings/search/CustomSiteMapRegistry.java @@ -19,9 +19,17 @@ package com.android.settings.search; import android.util.ArrayMap; import com.android.settings.DisplaySettings; +import com.android.settings.backup.UserBackupSettingsActivity; +import com.android.settings.connecteddevice.ConnectedDeviceDashboardFragment; +import com.android.settings.connecteddevice.usb.UsbDetailsFragment; +import com.android.settings.fuelgauge.PowerUsageAdvanced; +import com.android.settings.fuelgauge.PowerUsageSummary; +import com.android.settings.location.LocationSettings; +import com.android.settings.location.RecentLocationRequestSeeAllFragment; import com.android.settings.network.NetworkDashboardFragment; import com.android.settings.security.SecuritySettings; import com.android.settings.security.screenlock.ScreenLockSettings; +import com.android.settings.system.SystemDashboardFragment; import com.android.settings.wallpaper.WallpaperSuggestionActivity; import com.android.settings.wifi.WifiSettings2; @@ -44,5 +52,12 @@ public class CustomSiteMapRegistry { WallpaperSuggestionActivity.class.getName(), DisplaySettings.class.getName()); CUSTOM_SITE_MAP.put( WifiSettings2.class.getName(), NetworkDashboardFragment.class.getName()); + CUSTOM_SITE_MAP.put(PowerUsageAdvanced.class.getName(), PowerUsageSummary.class.getName()); + CUSTOM_SITE_MAP.put(RecentLocationRequestSeeAllFragment.class.getName(), + LocationSettings.class.getName()); + CUSTOM_SITE_MAP.put(UsbDetailsFragment.class.getName(), + ConnectedDeviceDashboardFragment.class.getName()); + CUSTOM_SITE_MAP.put(UserBackupSettingsActivity.class.getName(), + SystemDashboardFragment.class.getName()); } } diff --git a/tests/robotests/src/com/android/settings/search/CustomSiteMapRegistryTest.java b/tests/robotests/src/com/android/settings/search/CustomSiteMapRegistryTest.java index 5bd4538dfa5..5c78a6bde68 100644 --- a/tests/robotests/src/com/android/settings/search/CustomSiteMapRegistryTest.java +++ b/tests/robotests/src/com/android/settings/search/CustomSiteMapRegistryTest.java @@ -19,9 +19,17 @@ package com.android.settings.search; import static com.google.common.truth.Truth.assertThat; import com.android.settings.DisplaySettings; +import com.android.settings.backup.UserBackupSettingsActivity; +import com.android.settings.connecteddevice.ConnectedDeviceDashboardFragment; +import com.android.settings.connecteddevice.usb.UsbDetailsFragment; +import com.android.settings.fuelgauge.PowerUsageAdvanced; +import com.android.settings.fuelgauge.PowerUsageSummary; +import com.android.settings.location.LocationSettings; +import com.android.settings.location.RecentLocationRequestSeeAllFragment; import com.android.settings.network.NetworkDashboardFragment; import com.android.settings.security.SecuritySettings; import com.android.settings.security.screenlock.ScreenLockSettings; +import com.android.settings.system.SystemDashboardFragment; import com.android.settings.wallpaper.WallpaperSuggestionActivity; import com.android.settings.wifi.WifiSettings2; @@ -50,4 +58,31 @@ public class CustomSiteMapRegistryTest { assertThat(CustomSiteMapRegistry.CUSTOM_SITE_MAP.get(WifiSettings2.class.getName())) .isEqualTo(NetworkDashboardFragment.class.getName()); } + + @Test + public void shouldContainPowerUsageAdvancedPairs() { + assertThat(CustomSiteMapRegistry.CUSTOM_SITE_MAP.get(PowerUsageAdvanced.class.getName())) + .isEqualTo(PowerUsageSummary.class.getName()); + } + + @Test + public void shouldContainRecentLocationRequestSeeAllFragmentPairs() { + assertThat(CustomSiteMapRegistry.CUSTOM_SITE_MAP.get( + RecentLocationRequestSeeAllFragment.class.getName())).isEqualTo( + LocationSettings.class.getName()); + } + + @Test + public void shouldContainUsbDetailsFragmentPairs() { + assertThat(CustomSiteMapRegistry.CUSTOM_SITE_MAP.get( + UsbDetailsFragment.class.getName())).isEqualTo( + ConnectedDeviceDashboardFragment.class.getName()); + } + + @Test + public void shouldContainUserBackupSettingsActivityPairs() { + assertThat(CustomSiteMapRegistry.CUSTOM_SITE_MAP.get( + UserBackupSettingsActivity.class.getName())).isEqualTo( + SystemDashboardFragment.class.getName()); + } } From ecb66ce790dafe976bb55d00697cc1e13898d238 Mon Sep 17 00:00:00 2001 From: Julia Reynolds Date: Fri, 10 Apr 2020 15:34:19 -0400 Subject: [PATCH 3/7] Fixes for notification history - Fix some crashes - Fix layout in landscape - Fix a11y readout Test: manual Fixes: 153510934 Fixes: 153554113 Fixes: 153407364 Fixes: 152728558 Change-Id: I6c6bb10d4a67ece61fbf109b4289c4f368206788 --- res/layout/notification_history.xml | 28 ++------ .../notification_history_app_layout.xml | 8 +-- .../history/NotificationHistoryActivity.java | 2 +- .../history/NotificationHistoryAdapter.java | 42 +++++++++++- .../NotificationHistoryRecyclerView.java | 1 + .../NotificationHistoryViewHolder.java | 34 ---------- .../history/NotificationSbnViewHolder.java | 64 ++++++++++--------- 7 files changed, 85 insertions(+), 94 deletions(-) diff --git a/res/layout/notification_history.xml b/res/layout/notification_history.xml index 0e7f6b0210d..f5fae3f606f 100644 --- a/res/layout/notification_history.xml +++ b/res/layout/notification_history.xml @@ -14,7 +14,7 @@ limitations under the License. --> - - - - - - - - - \ No newline at end of file + \ No newline at end of file diff --git a/res/layout/notification_history_app_layout.xml b/res/layout/notification_history_app_layout.xml index a8757fe707e..e8d33166c9d 100644 --- a/res/layout/notification_history_app_layout.xml +++ b/res/layout/notification_history_app_layout.xml @@ -73,18 +73,12 @@ android:layout_height="1dp" android:background="?android:attr/listDivider"/> - - - \ No newline at end of file diff --git a/src/com/android/settings/notification/history/NotificationHistoryActivity.java b/src/com/android/settings/notification/history/NotificationHistoryActivity.java index d41268dcc53..73befeb4801 100644 --- a/src/com/android/settings/notification/history/NotificationHistoryActivity.java +++ b/src/com/android/settings/notification/history/NotificationHistoryActivity.java @@ -77,7 +77,7 @@ public class NotificationHistoryActivity extends Activity { View viewForPackage = LayoutInflater.from(this) .inflate(R.layout.notification_history_app_layout, null); - final View container = viewForPackage.findViewById(R.id.list_container); + final View container = viewForPackage.findViewById(R.id.notification_list); container.setVisibility(View.GONE); ImageButton expand = viewForPackage.findViewById(R.id.expand); expand.setContentDescription(container.getVisibility() == View.VISIBLE diff --git a/src/com/android/settings/notification/history/NotificationHistoryAdapter.java b/src/com/android/settings/notification/history/NotificationHistoryAdapter.java index a06939ac4d1..9d652d97f2c 100644 --- a/src/com/android/settings/notification/history/NotificationHistoryAdapter.java +++ b/src/com/android/settings/notification/history/NotificationHistoryAdapter.java @@ -16,13 +16,22 @@ package com.android.settings.notification.history; +import static android.provider.Settings.EXTRA_APP_PACKAGE; +import static android.provider.Settings.EXTRA_CHANNEL_ID; +import static android.provider.Settings.EXTRA_CONVERSATION_ID; + import android.app.INotificationManager; import android.app.NotificationHistory.HistoricalNotification; +import android.content.Intent; +import android.os.Bundle; import android.os.RemoteException; +import android.os.UserHandle; +import android.provider.Settings; import android.util.Slog; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; +import android.view.accessibility.AccessibilityNodeInfo; import androidx.annotation.NonNull; import androidx.recyclerview.widget.RecyclerView; @@ -63,8 +72,37 @@ public class NotificationHistoryAdapter extends holder.setTitle(hn.getTitle()); holder.setSummary(hn.getText()); holder.setPostedTime(hn.getPostedTimeMs()); - holder.addOnClick(hn.getPackage(), hn.getUserId(), hn.getChannelId(), - hn.getConversationId()); + holder.itemView.setOnClickListener(v -> { + Intent intent = new Intent(Settings.ACTION_CHANNEL_NOTIFICATION_SETTINGS) + .putExtra(EXTRA_APP_PACKAGE, hn.getPackage()) + .putExtra(EXTRA_CHANNEL_ID, hn.getChannelId()) + .putExtra(EXTRA_CONVERSATION_ID, hn.getConversationId()); + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + holder.itemView.getContext().startActivityAsUser(intent, UserHandle.of(hn.getUserId())); + }); + holder.itemView.setAccessibilityDelegate(new View.AccessibilityDelegate() { + @Override + public void onInitializeAccessibilityNodeInfo(View host, + AccessibilityNodeInfo info) { + super.onInitializeAccessibilityNodeInfo(host, info); + CharSequence description = + host.getResources().getText(R.string.notification_history_view_settings); + AccessibilityNodeInfo.AccessibilityAction customClick = + new AccessibilityNodeInfo.AccessibilityAction( + AccessibilityNodeInfo.ACTION_CLICK, description); + info.addAction(customClick); + //info.addAction(AccessibilityNodeInfo.AccessibilityAction.ACTION_DISMISS); + } + + @Override + public boolean performAccessibilityAction(View host, int action, Bundle args) { + if (action == AccessibilityNodeInfo.AccessibilityAction.ACTION_DISMISS.getId()) { + onItemSwipeDeleted(position); + return true; + } + return false; + } + }); } @Override diff --git a/src/com/android/settings/notification/history/NotificationHistoryRecyclerView.java b/src/com/android/settings/notification/history/NotificationHistoryRecyclerView.java index eaaa7c99edf..6f6deb073fe 100644 --- a/src/com/android/settings/notification/history/NotificationHistoryRecyclerView.java +++ b/src/com/android/settings/notification/history/NotificationHistoryRecyclerView.java @@ -34,6 +34,7 @@ public class NotificationHistoryRecyclerView extends RecyclerView { ItemTouchHelper touchHelper = new ItemTouchHelper( new DismissTouchHelper(0, ItemTouchHelper.START | ItemTouchHelper.END)); touchHelper.attachToRecyclerView(this); + setNestedScrollingEnabled(false); } public void setOnItemSwipeDeleteListener(OnItemSwipeDeleteListener listener) { diff --git a/src/com/android/settings/notification/history/NotificationHistoryViewHolder.java b/src/com/android/settings/notification/history/NotificationHistoryViewHolder.java index d1f47afad85..ef4f0da3bd9 100644 --- a/src/com/android/settings/notification/history/NotificationHistoryViewHolder.java +++ b/src/com/android/settings/notification/history/NotificationHistoryViewHolder.java @@ -16,20 +16,10 @@ package com.android.settings.notification.history; -import static android.provider.Settings.EXTRA_APP_PACKAGE; -import static android.provider.Settings.EXTRA_CHANNEL_ID; -import static android.provider.Settings.EXTRA_CONVERSATION_ID; - -import android.content.Intent; -import android.os.UserHandle; -import android.provider.Settings; import android.view.View; import android.widget.DateTimeView; import android.widget.TextView; -import androidx.core.view.AccessibilityDelegateCompat; -import androidx.core.view.ViewCompat; -import androidx.core.view.accessibility.AccessibilityNodeInfoCompat; import androidx.recyclerview.widget.RecyclerView; import com.android.settings.R; @@ -61,28 +51,4 @@ public class NotificationHistoryViewHolder extends RecyclerView.ViewHolder { void setPostedTime(long postedTime) { mTime.setTime(postedTime); } - - void addOnClick(String pkg, int userId, String channelId, String conversationId) { - itemView.setOnClickListener(v -> { - Intent intent = new Intent(Settings.ACTION_CHANNEL_NOTIFICATION_SETTINGS) - .putExtra(EXTRA_APP_PACKAGE, pkg) - .putExtra(EXTRA_CHANNEL_ID, channelId) - .putExtra(EXTRA_CONVERSATION_ID, conversationId); - intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - itemView.getContext().startActivityAsUser(intent, UserHandle.of(userId)); - }); - ViewCompat.setAccessibilityDelegate(itemView, new AccessibilityDelegateCompat() { - @Override - public void onInitializeAccessibilityNodeInfo(View host, - AccessibilityNodeInfoCompat info) { - super.onInitializeAccessibilityNodeInfo(host, info); - CharSequence description = - host.getResources().getText(R.string.notification_history_view_settings); - AccessibilityNodeInfoCompat.AccessibilityActionCompat customClick = - new AccessibilityNodeInfoCompat.AccessibilityActionCompat( - AccessibilityNodeInfoCompat.ACTION_CLICK, description); - info.addAction(customClick); - } - }); - } } diff --git a/src/com/android/settings/notification/history/NotificationSbnViewHolder.java b/src/com/android/settings/notification/history/NotificationSbnViewHolder.java index dabf3f3dd46..42a210057a8 100644 --- a/src/com/android/settings/notification/history/NotificationSbnViewHolder.java +++ b/src/com/android/settings/notification/history/NotificationSbnViewHolder.java @@ -20,6 +20,7 @@ import android.app.PendingIntent; import android.content.ActivityNotFoundException; import android.content.Intent; import android.graphics.drawable.Drawable; +import android.os.Bundle; import android.os.UserHandle; import android.text.TextUtils; import android.util.Slog; @@ -81,39 +82,44 @@ public class NotificationSbnViewHolder extends RecyclerView.ViewHolder { void setProfileBadge(Drawable badge) { mProfileBadge.setImageDrawable(badge); + mProfileBadge.setVisibility(badge != null ? View.VISIBLE : View.GONE); } void addOnClick(String pkg, int userId, PendingIntent pi) { - itemView.setOnClickListener(v -> { - if (pi != null) { - try { - pi.send(); - } catch (PendingIntent.CanceledException e) { - Slog.e(TAG, "Could not launch", e); + Intent appIntent = itemView.getContext().getPackageManager() + .getLaunchIntentForPackage(pkg); + boolean isPendingIntentValid = pi != null && PendingIntent.getActivity( + itemView.getContext(), 0, pi.getIntent(), PendingIntent.FLAG_NO_CREATE) != null; + if (isPendingIntentValid || appIntent != null) { + itemView.setOnClickListener(v -> { + if (pi != null) { + try { + pi.send(); + } catch (PendingIntent.CanceledException e) { + Slog.e(TAG, "Could not launch", e); + } + } else if (appIntent != null) { + appIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + try { + itemView.getContext().startActivityAsUser(appIntent, UserHandle.of(userId)); + } catch (ActivityNotFoundException e) { + Slog.e(TAG, "no launch activity", e); + } } - } else { - Intent appIntent = itemView.getContext().getPackageManager() - .getLaunchIntentForPackage(pkg); - appIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - try { - itemView.getContext().startActivityAsUser(appIntent, UserHandle.of(userId)); - } catch (ActivityNotFoundException e) { - Slog.e(TAG, "no launch activity", e); + }); + ViewCompat.setAccessibilityDelegate(itemView, new AccessibilityDelegateCompat() { + @Override + public void onInitializeAccessibilityNodeInfo(View host, + AccessibilityNodeInfoCompat info) { + super.onInitializeAccessibilityNodeInfo(host, info); + CharSequence description = host.getResources().getText( + R.string.notification_history_open_notification); + AccessibilityNodeInfoCompat.AccessibilityActionCompat customClick = + new AccessibilityNodeInfoCompat.AccessibilityActionCompat( + AccessibilityNodeInfoCompat.ACTION_CLICK, description); + info.addAction(customClick); } - } - }); - ViewCompat.setAccessibilityDelegate(itemView, new AccessibilityDelegateCompat() { - @Override - public void onInitializeAccessibilityNodeInfo(View host, - AccessibilityNodeInfoCompat info) { - super.onInitializeAccessibilityNodeInfo(host, info); - CharSequence description = host.getResources().getText( - R.string.notification_history_open_notification); - AccessibilityNodeInfoCompat.AccessibilityActionCompat customClick = - new AccessibilityNodeInfoCompat.AccessibilityActionCompat( - AccessibilityNodeInfoCompat.ACTION_CLICK, description); - info.addAction(customClick); - } - }); + }); + } } } From cfd862db37addeea524e4905e88f9dbea5b8be05 Mon Sep 17 00:00:00 2001 From: Tim Peng Date: Mon, 13 Apr 2020 14:44:53 +0800 Subject: [PATCH 4/7] Tapping on Play media can have up to a 1 minute delay -Set Output Switcher activity in PendingIntent -Broadcast is super lagged right after reboot -Not to send broadcast to itself in order to launch Output Switcher -Add test case Bug: 152909957 Test: make -j42 RunSettingsRoboTests Change-Id: I17280a3bb9e47aa6050cfaf1463c780cd9849ad7 --- .../media/MediaOutputIndicatorSlice.java | 50 ++++++++----------- .../media/MediaOutputIndicatorSliceTest.java | 45 +++++------------ 2 files changed, 32 insertions(+), 63 deletions(-) diff --git a/src/com/android/settings/media/MediaOutputIndicatorSlice.java b/src/com/android/settings/media/MediaOutputIndicatorSlice.java index f336f279295..63dd2dee8d8 100644 --- a/src/com/android/settings/media/MediaOutputIndicatorSlice.java +++ b/src/com/android/settings/media/MediaOutputIndicatorSlice.java @@ -25,8 +25,8 @@ import android.content.Intent; import android.graphics.Bitmap; import android.media.session.MediaController; import android.net.Uri; -import android.util.Log; +import androidx.annotation.VisibleForTesting; import androidx.core.graphics.drawable.IconCompat; import androidx.slice.Slice; import androidx.slice.builders.ListBuilder; @@ -36,7 +36,6 @@ import com.android.settings.R; import com.android.settings.Utils; import com.android.settings.slices.CustomSliceable; import com.android.settings.slices.SliceBackgroundWorker; -import com.android.settings.slices.SliceBroadcastReceiver; import com.android.settingslib.media.MediaOutputSliceConstants; public class MediaOutputIndicatorSlice implements CustomSliceable { @@ -60,8 +59,10 @@ public class MediaOutputIndicatorSlice implements CustomSliceable { final IconCompat icon = IconCompat.createWithResource(mContext, com.android.internal.R.drawable.ic_settings_bluetooth); final CharSequence title = mContext.getText(R.string.media_output_title); + final PendingIntent primaryActionIntent = PendingIntent.getActivity(mContext, + 0 /* requestCode */, getMediaOutputSliceIntent(), 0 /* flags */); final SliceAction primarySliceAction = SliceAction.createDeeplink( - getBroadcastIntent(), icon, ListBuilder.ICON_IMAGE, title); + primaryActionIntent, icon, ListBuilder.ICON_IMAGE, title); @ColorInt final int color = Utils.getColorAccentDefaultColor(mContext); // To set an empty icon to indent the row final ListBuilder listBuilder = new ListBuilder(mContext, getUri(), ListBuilder.INFINITY) @@ -74,18 +75,27 @@ public class MediaOutputIndicatorSlice implements CustomSliceable { return listBuilder.build(); } + @VisibleForTesting + Intent getMediaOutputSliceIntent() { + final MediaController mediaController = getWorker().getActiveLocalMediaController(); + final Intent intent = new Intent() + .setPackage(Utils.SETTINGS_PACKAGE_NAME) + .setAction(MediaOutputSliceConstants.ACTION_MEDIA_OUTPUT) + .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + if (mediaController != null) { + intent.putExtra(MediaOutputSliceConstants.KEY_MEDIA_SESSION_TOKEN, + mediaController.getSessionToken()); + intent.putExtra(MediaOutputSliceConstants.EXTRA_PACKAGE_NAME, + mediaController.getPackageName()); + } + return intent; + } + private IconCompat createEmptyIcon() { final Bitmap bitmap = Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888); return IconCompat.createWithBitmap(bitmap); } - private PendingIntent getBroadcastIntent() { - final Intent intent = new Intent(getUri().toString()); - intent.setClass(mContext, SliceBroadcastReceiver.class); - return PendingIntent.getBroadcast(mContext, 0, intent, - PendingIntent.FLAG_UPDATE_CURRENT); - } - @Override public Uri getUri() { return MEDIA_OUTPUT_INDICATOR_SLICE_URI; @@ -103,26 +113,6 @@ public class MediaOutputIndicatorSlice implements CustomSliceable { return MediaOutputIndicatorWorker.class; } - @Override - public void onNotifyChange(Intent i) { - if (getWorker() == null) { - Log.d(TAG, "onNotifyChange: Worker is null"); - return; - } - final MediaController mediaController = getWorker().getActiveLocalMediaController(); - final Intent intent = new Intent() - .setPackage(Utils.SETTINGS_PACKAGE_NAME) - .setAction(MediaOutputSliceConstants.ACTION_MEDIA_OUTPUT) - .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - if (mediaController != null) { - intent.putExtra(MediaOutputSliceConstants.KEY_MEDIA_SESSION_TOKEN, - mediaController.getSessionToken()); - intent.putExtra(MediaOutputSliceConstants.EXTRA_PACKAGE_NAME, - mediaController.getPackageName()); - } - mContext.startActivity(intent); - } - private MediaOutputIndicatorWorker getWorker() { if (mWorker == null) { mWorker = SliceBackgroundWorker.getInstance(getUri()); diff --git a/tests/robotests/src/com/android/settings/media/MediaOutputIndicatorSliceTest.java b/tests/robotests/src/com/android/settings/media/MediaOutputIndicatorSliceTest.java index 55cc4cd57a3..1fc39105804 100644 --- a/tests/robotests/src/com/android/settings/media/MediaOutputIndicatorSliceTest.java +++ b/tests/robotests/src/com/android/settings/media/MediaOutputIndicatorSliceTest.java @@ -21,11 +21,8 @@ import static com.android.settings.slices.CustomSliceRegistry.MEDIA_OUTPUT_INDIC import static com.google.common.truth.Truth.assertThat; -import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.never; import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import android.content.Context; @@ -48,14 +45,12 @@ import com.android.settings.Utils; import com.android.settings.slices.SliceBackgroundWorker; import com.android.settings.testutils.shadow.ShadowBluetoothUtils; import com.android.settingslib.bluetooth.LocalBluetoothManager; -import com.android.settingslib.media.LocalMediaManager; import com.android.settingslib.media.MediaDevice; import com.android.settingslib.media.MediaOutputSliceConstants; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; -import org.mockito.ArgumentCaptor; import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.robolectric.RobolectricTestRunner; @@ -85,8 +80,6 @@ public class MediaOutputIndicatorSliceTest { @Mock private MediaController mMediaController; @Mock - private LocalMediaManager mLocalMediaManager; - @Mock private MediaDevice mDevice1; @Mock private MediaDevice mDevice2; @@ -193,46 +186,32 @@ public class MediaOutputIndicatorSliceTest { } @Test - public void onNotifyChange_noWorker_doNothing() { - sMediaOutputIndicatorWorker = null; - mMediaOutputIndicatorSlice.onNotifyChange(new Intent()); - - verify(mContext, never()).startActivity(any()); - } - - @Test - public void onNotifyChange_withActiveLocalMedia_verifyIntentExtra() { + public void getMediaOutputSliceIntent_withActiveLocalMedia_verifyIntentExtra() { when(mMediaController.getSessionToken()).thenReturn(mToken); when(mMediaController.getPackageName()).thenReturn(TEST_PACKAGE_NAME); doReturn(mMediaController).when(sMediaOutputIndicatorWorker) .getActiveLocalMediaController(); + final Intent intent = mMediaOutputIndicatorSlice.getMediaOutputSliceIntent(); - final ArgumentCaptor intentCaptor = ArgumentCaptor.forClass(Intent.class); - mMediaOutputIndicatorSlice.onNotifyChange(new Intent()); - verify(mContext).startActivity(intentCaptor.capture()); - - assertThat(TextUtils.equals(TEST_PACKAGE_NAME, intentCaptor.getValue().getStringExtra( + assertThat(TextUtils.equals(TEST_PACKAGE_NAME, intent.getStringExtra( MediaOutputSliceConstants.EXTRA_PACKAGE_NAME))).isTrue(); - assertThat(TextUtils.equals(Utils.SETTINGS_PACKAGE_NAME, intentCaptor.getValue() - .getPackage())).isTrue(); - assertThat(mToken == intentCaptor.getValue().getExtras().getParcelable( + assertThat(MediaOutputSliceConstants.ACTION_MEDIA_OUTPUT).isEqualTo(intent.getAction()); + assertThat(TextUtils.equals(Utils.SETTINGS_PACKAGE_NAME, intent.getPackage())).isTrue(); + assertThat(mToken == intent.getExtras().getParcelable( MediaOutputSliceConstants.KEY_MEDIA_SESSION_TOKEN)).isTrue(); } @Test - public void onNotifyChange_withoutActiveLocalMedia_verifyIntentExtra() { + public void getMediaOutputSliceIntent_withoutActiveLocalMedia_verifyIntentExtra() { doReturn(mMediaController).when(sMediaOutputIndicatorWorker) .getActiveLocalMediaController(); + final Intent intent = mMediaOutputIndicatorSlice.getMediaOutputSliceIntent(); - final ArgumentCaptor intentCaptor = ArgumentCaptor.forClass(Intent.class); - mMediaOutputIndicatorSlice.onNotifyChange(new Intent()); - verify(mContext).startActivity(intentCaptor.capture()); - - assertThat(TextUtils.isEmpty(intentCaptor.getValue().getStringExtra( + assertThat(TextUtils.isEmpty(intent.getStringExtra( MediaOutputSliceConstants.EXTRA_PACKAGE_NAME))).isTrue(); - assertThat(TextUtils.equals(Utils.SETTINGS_PACKAGE_NAME, intentCaptor.getValue() - .getPackage())).isTrue(); - assertThat(intentCaptor.getValue().getExtras().getParcelable( + assertThat(MediaOutputSliceConstants.ACTION_MEDIA_OUTPUT).isEqualTo(intent.getAction()); + assertThat(TextUtils.equals(Utils.SETTINGS_PACKAGE_NAME, intent.getPackage())).isTrue(); + assertThat(intent.getExtras().getParcelable( MediaOutputSliceConstants.KEY_MEDIA_SESSION_TOKEN) == null).isTrue(); } From 4601d6208961596d936810b6d78d9d1540dec9fd Mon Sep 17 00:00:00 2001 From: Arc Wang Date: Mon, 13 Apr 2020 14:59:49 +0800 Subject: [PATCH 5/7] [Wi-Fi] Fix NetworkRequestErrorDialogFragment exception when rotation When rotating an androidx fragment, it uses default constructor to instantiate the new fragment instance. Every androidx fragment should not set private scope to it's default constructor. Bug: 153824549 Test: make RunSettingsRoboTests ROBOTEST_FILTER=NetworkRequestErrorDialogFragmentTest Change-Id: Ie1be0e033aa85d37cb4d85193b05beab72d4d8e7 --- .../wifi/NetworkRequestErrorDialogFragment.java | 5 +---- .../NetworkRequestErrorDialogFragmentTest.java | 14 ++++++++++++++ 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/src/com/android/settings/wifi/NetworkRequestErrorDialogFragment.java b/src/com/android/settings/wifi/NetworkRequestErrorDialogFragment.java index 57e1bcaa681..aebd072c80a 100644 --- a/src/com/android/settings/wifi/NetworkRequestErrorDialogFragment.java +++ b/src/com/android/settings/wifi/NetworkRequestErrorDialogFragment.java @@ -25,6 +25,7 @@ import android.os.Bundle; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.appcompat.app.AlertDialog; + import com.android.settings.R; import com.android.settings.core.instrumentation.InstrumentedDialogFragment; @@ -44,10 +45,6 @@ public class NetworkRequestErrorDialogFragment extends InstrumentedDialogFragmen return new NetworkRequestErrorDialogFragment(); } - private NetworkRequestErrorDialogFragment() { - super(); - } - @Override public void onCancel(@NonNull DialogInterface dialog) { super.onCancel(dialog); diff --git a/tests/robotests/src/com/android/settings/wifi/NetworkRequestErrorDialogFragmentTest.java b/tests/robotests/src/com/android/settings/wifi/NetworkRequestErrorDialogFragmentTest.java index c4bdda8f0d7..333c4eb6101 100644 --- a/tests/robotests/src/com/android/settings/wifi/NetworkRequestErrorDialogFragmentTest.java +++ b/tests/robotests/src/com/android/settings/wifi/NetworkRequestErrorDialogFragmentTest.java @@ -17,6 +17,8 @@ package com.android.settings.wifi; import static com.google.common.truth.Truth.assertThat; + +import static org.junit.Assert.fail; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; @@ -26,12 +28,15 @@ import android.content.DialogInterface; import android.net.wifi.WifiManager.NetworkRequestUserSelectionCallback; import android.os.Bundle; import android.widget.Button; + import androidx.appcompat.app.AlertDialog; + import com.android.settings.R; import com.android.settings.testutils.shadow.ShadowAlertDialogCompat; import com.android.settings.wifi.NetworkRequestErrorDialogFragment.ERROR_DIALOG_TYPE; import com.android.settingslib.wifi.WifiTracker; import com.android.settingslib.wifi.WifiTrackerFactory; + import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -57,6 +62,15 @@ public class NetworkRequestErrorDialogFragmentTest { mFragment.show(mActivity.getSupportFragmentManager(), null); } + @Test + public void getConstructor_shouldNotThrowNoSuchMethodException() { + try { + NetworkRequestErrorDialogFragment.class.getConstructor(); + } catch (NoSuchMethodException e) { + fail("No default constructor for configuration change!"); + } + } + @Test public void display_shouldShowTimeoutDialog() { AlertDialog alertDialog = ShadowAlertDialogCompat.getLatestAlertDialog(); From 3562ec319682b1b9d91101290494140a07522faf Mon Sep 17 00:00:00 2001 From: Howard Chen Date: Wed, 1 Apr 2020 14:39:06 +0800 Subject: [PATCH 6/7] Pathfind a way to Validate DSU before releasing GSI Provide an alternative DSU portal for testing. It can be enabled or disabled with the setprop command. Test: Developer Settings -> DSULoader and check logcat Bug: 152403883 Change-Id: Id1a7bb2a03d7243299f639e654a1c1a086b87545 --- src/com/android/settings/development/DSULoader.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/com/android/settings/development/DSULoader.java b/src/com/android/settings/development/DSULoader.java index 4727369e5a8..1c897c47ab6 100644 --- a/src/com/android/settings/development/DSULoader.java +++ b/src/com/android/settings/development/DSULoader.java @@ -65,7 +65,8 @@ public class DSULoader extends ListActivity { private static final String PROPERTY_KEY_CPU = "ro.product.cpu.abi"; private static final String PROPERTY_KEY_OS = "ro.system.build.version.release"; private static final String PROPERTY_KEY_VNDK = "ro.vndk.version"; - private static final String PROPERTY_KEY_LIST = "ro.vendor.dsu.list"; + private static final String PROPERTY_KEY_LIST = + "persist.sys.fflag.override.settings_dynamic_system.list"; private static final String PROPERTY_KEY_SPL = "ro.build.version.security_patch"; private static final String DSU_LIST = "https://dl.google.com/developers/android/gsi/gsi-src.json"; From eb0531f0dfc484cbe277a4466662c21fabe54121 Mon Sep 17 00:00:00 2001 From: Tim Peng Date: Mon, 13 Apr 2020 15:25:33 +0800 Subject: [PATCH 7/7] Output switcher subtitle modification -Change from null to "Switch output" -Update test case Bug: 153834179 Test: make -j42 RunSettingsRoboTests Change-Id: I184e78292e982f8a93b74612331a1d2cab28d07a --- .../android/settings/panel/MediaOutputPanel.java | 2 +- .../settings/panel/MediaOutputPanelTest.java | 16 +++++++++------- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/src/com/android/settings/panel/MediaOutputPanel.java b/src/com/android/settings/panel/MediaOutputPanel.java index 56ed6fbe8ce..1bf6f26ece5 100644 --- a/src/com/android/settings/panel/MediaOutputPanel.java +++ b/src/com/android/settings/panel/MediaOutputPanel.java @@ -103,7 +103,7 @@ public class MediaOutputPanel implements PanelContent, LocalMediaManager.DeviceC return metadata.getDescription().getSubtitle(); } } - return null; + return mContext.getText(R.string.media_output_panel_title); } @Override diff --git a/tests/robotests/src/com/android/settings/panel/MediaOutputPanelTest.java b/tests/robotests/src/com/android/settings/panel/MediaOutputPanelTest.java index e0b926b8a68..cdfa87f05fd 100644 --- a/tests/robotests/src/com/android/settings/panel/MediaOutputPanelTest.java +++ b/tests/robotests/src/com/android/settings/panel/MediaOutputPanelTest.java @@ -35,7 +35,6 @@ import android.media.session.MediaController; import android.media.session.MediaSessionManager; import android.media.session.PlaybackState; import android.net.Uri; -import android.text.TextUtils; import com.android.settings.R; import com.android.settings.slices.CustomSliceRegistry; @@ -238,28 +237,31 @@ public class MediaOutputPanelTest { } @Test - public void getSubTitle_noMetadata_returnEmpty() { + public void getSubTitle_noMetadata_returnDefault() { when(mMediaController.getPackageName()).thenReturn(TEST_PACKAGENAME); when(mMediaController.getMetadata()).thenReturn(null); - assertThat(TextUtils.isEmpty(mPanel.getSubTitle())).isTrue(); + assertThat(mPanel.getSubTitle()).isEqualTo(mContext.getText( + R.string.media_output_panel_title)); } @Test - public void getSubTitle_noPackageName_returnEmpty() { + public void getSubTitle_noPackageName_returnDefault() { mPanel = MediaOutputPanel.create(mContext, null); when(mMediaController.getMetadata()).thenReturn(mMediaMetadata); - assertThat(TextUtils.isEmpty(mPanel.getSubTitle())).isTrue(); + assertThat(mPanel.getSubTitle()).isEqualTo(mContext.getText( + R.string.media_output_panel_title)); } @Test - public void getSubTitle_noController_returnEmpty() { + public void getSubTitle_noController_returnDefault() { mMediaControllers.clear(); mPanel = MediaOutputPanel.create(mContext, TEST_PACKAGENAME); when(mMediaController.getMetadata()).thenReturn(mMediaMetadata); - assertThat(TextUtils.isEmpty(mPanel.getSubTitle())).isTrue(); + assertThat(mPanel.getSubTitle()).isEqualTo(mContext.getText( + R.string.media_output_panel_title)); } @Test