diff options
author | android-build-team Robot <android-build-team-robot@google.com> | 2019-07-02 03:03:56 +0000 |
---|---|---|
committer | android-build-team Robot <android-build-team-robot@google.com> | 2019-07-02 03:03:56 +0000 |
commit | c1005749f6078907c63f9994097e889e8633df2f (patch) | |
tree | 3d0682c0d338ec85c95279caf4cc58ccc68e09ee | |
parent | 1fcb598947053316133bb18ca98bd1788c4ecad9 (diff) | |
parent | bce828f157d905bc7f731fc400bdc0466bdfbfa1 (diff) | |
download | base-c1005749f6078907c63f9994097e889e8633df2f.tar.gz |
Snap for 5702388 from bce828f157d905bc7f731fc400bdc0466bdfbfa1 to qt-aml-release
Change-Id: Icdc93783eb1becab6f2c98c7f0b22817f92ee907
5 files changed, 103 insertions, 9 deletions
diff --git a/packages/SettingsLib/res/values-hi/strings.xml b/packages/SettingsLib/res/values-hi/strings.xml index 8c6ff8e51f88..5d512a84ef99 100644 --- a/packages/SettingsLib/res/values-hi/strings.xml +++ b/packages/SettingsLib/res/values-hi/strings.xml @@ -37,7 +37,7 @@ <string name="wifi_no_internet" msgid="4663834955626848401">"इंटरनेट नहीं है"</string> <string name="saved_network" msgid="4352716707126620811">"<xliff:g id="NAME">%1$s</xliff:g> के द्वारा सहेजा गया"</string> <string name="connected_via_network_scorer" msgid="5713793306870815341">"%1$s के ज़रिए ऑटोमैटिक रूप से कनेक्ट है"</string> - <string name="connected_via_network_scorer_default" msgid="7867260222020343104">"नेटवर्क रेटिंग प्रदाता के ज़रिए अपने आप कनेक्ट है"</string> + <string name="connected_via_network_scorer_default" msgid="7867260222020343104">"नेटवर्क रेटिंग कंपनी के ज़रिए अपने आप कनेक्ट है"</string> <string name="connected_via_passpoint" msgid="2826205693803088747">"%1$s के द्वारा उपलब्ध"</string> <string name="connected_via_app" msgid="5571999941988929520">"<xliff:g id="NAME">%1$s</xliff:g> के ज़रिए कनेक्ट किया गया"</string> <string name="available_via_passpoint" msgid="1617440946846329613">"%1$s के द्वारा उपलब्ध"</string> diff --git a/packages/SettingsLib/res/values-in/strings.xml b/packages/SettingsLib/res/values-in/strings.xml index 0684b3d292a5..798ea3c80cb0 100644 --- a/packages/SettingsLib/res/values-in/strings.xml +++ b/packages/SettingsLib/res/values-in/strings.xml @@ -41,7 +41,7 @@ <string name="connected_via_passpoint" msgid="2826205693803088747">"Terhubung melalui %1$s"</string> <string name="connected_via_app" msgid="5571999941988929520">"Tersambung melalui <xliff:g id="NAME">%1$s</xliff:g>"</string> <string name="available_via_passpoint" msgid="1617440946846329613">"Tersedia melalui %1$s"</string> - <string name="tap_to_sign_up" msgid="6449724763052579434">"Tap untuk mendaftar"</string> + <string name="tap_to_sign_up" msgid="6449724763052579434">"Ketuk untuk mendaftar"</string> <string name="wifi_connected_no_internet" msgid="8202906332837777829">"Tersambung, tidak ada internet"</string> <string name="wifi_limited_connection" msgid="7717855024753201527">"Koneksi terbatas"</string> <string name="wifi_status_no_internet" msgid="5784710974669608361">"Tidak ada internet"</string> @@ -52,7 +52,7 @@ <string name="osu_opening_provider" msgid="5488997661548640424">"Membuka <xliff:g id="PASSPOINTPROVIDER">%1$s</xliff:g>"</string> <string name="osu_connect_failed" msgid="2187750899158158934">"Tidak dapat tersambung"</string> <string name="osu_completing_sign_up" msgid="9037638564719197082">"Menyelesaikan pendaftaran…"</string> - <string name="osu_sign_up_failed" msgid="7296159750352873260">"Tidak dapat menyelesaikan pendaftaran. Tap untuk mencoba lagi."</string> + <string name="osu_sign_up_failed" msgid="7296159750352873260">"Tidak dapat menyelesaikan pendaftaran. Ketuk untuk mencoba lagi."</string> <string name="osu_sign_up_complete" msgid="8207626049093289203">"Pendaftaran selesai. Menyambungkan…"</string> <string name="speed_label_very_slow" msgid="1867055264243608530">"Sangat Lambat"</string> <string name="speed_label_slow" msgid="813109590815810235">"Lambat"</string> @@ -338,7 +338,7 @@ <string name="enable_freeform_support_summary" msgid="8247310463288834487">"Aktifkan dukungan untuk jendela eksperimental berformat bebas."</string> <string name="local_backup_password_title" msgid="3860471654439418822">"Sandi backup desktop"</string> <string name="local_backup_password_summary_none" msgid="6951095485537767956">"Saat ini backup desktop sepenuhnya tidak dilindungi"</string> - <string name="local_backup_password_summary_change" msgid="5376206246809190364">"Tap guna mengubah atau menghapus sandi untuk cadangan lengkap desktop"</string> + <string name="local_backup_password_summary_change" msgid="5376206246809190364">"Ketuk guna mengubah atau menghapus sandi untuk cadangan lengkap desktop"</string> <string name="local_backup_password_toast_success" msgid="582016086228434290">"Sandi cadangan baru telah disetel"</string> <string name="local_backup_password_toast_confirmation_mismatch" msgid="7805892532752708288">"Sandi baru dan konfirmasinya tidak cocok."</string> <string name="local_backup_password_toast_validation_failure" msgid="5646377234895626531">"Gagal menyetel sandi cadangan"</string> @@ -354,8 +354,8 @@ <item msgid="5363960654009010371">"Warna yang dioptimalkan untuk konten digital"</item> </string-array> <string name="inactive_apps_title" msgid="9042996804461901648">"Aplikasi standby"</string> - <string name="inactive_app_inactive_summary" msgid="5091363706699855725">"Tidak aktif. Tap untuk beralih."</string> - <string name="inactive_app_active_summary" msgid="4174921824958516106">"Aktif. Tap untuk beralih."</string> + <string name="inactive_app_inactive_summary" msgid="5091363706699855725">"Tidak aktif. Ketuk untuk beralih."</string> + <string name="inactive_app_active_summary" msgid="4174921824958516106">"Aktif. Ketuk untuk beralih."</string> <string name="standby_bucket_summary" msgid="6567835350910684727">"Status standby aplikasi:<xliff:g id="BUCKET"> %s</xliff:g>"</string> <string name="runningservices_settings_title" msgid="8097287939865165213">"Layanan yang sedang berjalan"</string> <string name="runningservices_settings_summary" msgid="854608995821032748">"Melihat dan mengontrol layanan yang sedang berjalan"</string> diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationViewHierarchyManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationViewHierarchyManager.java index b70b45b9db84..792594e7a5e4 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationViewHierarchyManager.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationViewHierarchyManager.java @@ -16,8 +16,11 @@ package com.android.systemui.statusbar; +import static com.android.systemui.Dependency.MAIN_HANDLER_NAME; + import android.content.Context; import android.content.res.Resources; +import android.os.Handler; import android.os.Trace; import android.os.UserHandle; import android.util.Log; @@ -43,6 +46,7 @@ import java.util.List; import java.util.Stack; import javax.inject.Inject; +import javax.inject.Named; import javax.inject.Singleton; import dagger.Lazy; @@ -58,6 +62,8 @@ import dagger.Lazy; public class NotificationViewHierarchyManager implements DynamicPrivacyController.Listener { private static final String TAG = "NotificationViewHierarchyManager"; + private final Handler mHandler; + //TODO: change this top <Entry, List<Entry>>? private final HashMap<ExpandableNotificationRow, List<ExpandableNotificationRow>> mTmpChildOrderMap = new HashMap<>(); @@ -86,9 +92,13 @@ public class NotificationViewHierarchyManager implements DynamicPrivacyControlle // Used to help track down re-entrant calls to our update methods, which will cause bugs. private boolean mPerformingUpdate; + // Hack to get around re-entrant call in onDynamicPrivacyChanged() until we can track down + // the problem. + private boolean mIsHandleDynamicPrivacyChangeScheduled; @Inject public NotificationViewHierarchyManager(Context context, + @Named(MAIN_HANDLER_NAME) Handler mainHandler, NotificationLockscreenUserManager notificationLockscreenUserManager, NotificationGroupManager groupManager, VisualStabilityManager visualStabilityManager, @@ -97,6 +107,7 @@ public class NotificationViewHierarchyManager implements DynamicPrivacyControlle Lazy<ShadeController> shadeController, BubbleData bubbleData, DynamicPrivacyController privacyController) { + mHandler = mainHandler; mLockscreenUserManager = notificationLockscreenUserManager; mGroupManager = groupManager; mVisualStabilityManager = visualStabilityManager; @@ -435,6 +446,20 @@ public class NotificationViewHierarchyManager implements DynamicPrivacyControlle @Override public void onDynamicPrivacyChanged() { + if (mPerformingUpdate) { + Log.w(TAG, "onDynamicPrivacyChanged made a re-entrant call"); + } + // This listener can be called from updateNotificationViews() via a convoluted listener + // chain, so we post here to prevent a re-entrant call. See b/136186188 + // TODO: Refactor away the need for this + if (!mIsHandleDynamicPrivacyChangeScheduled) { + mIsHandleDynamicPrivacyChangeScheduled = true; + mHandler.post(this::onHandleDynamicPrivacyChanged); + } + } + + private void onHandleDynamicPrivacyChanged() { + mIsHandleDynamicPrivacyChangeScheduled = false; updateNotificationViews(); } diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationViewHierarchyManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationViewHierarchyManagerTest.java index c476d802c4e5..5103e8e89209 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationViewHierarchyManagerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationViewHierarchyManagerTest.java @@ -20,12 +20,16 @@ import static junit.framework.Assert.assertTrue; import static org.junit.Assert.assertEquals; import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.Mockito.clearInvocations; +import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; +import android.os.Handler; import android.testing.AndroidTestingRunner; import android.testing.TestableLooper; import android.view.View; @@ -78,13 +82,19 @@ public class NotificationViewHierarchyManagerTest extends SysuiTestCase { @Mock private VisualStabilityManager mVisualStabilityManager; @Mock private ShadeController mShadeController; + private TestableLooper mTestableLooper; + private Handler mHandler; private NotificationViewHierarchyManager mViewHierarchyManager; private NotificationTestHelper mHelper; + private boolean mMadeReentrantCall = false; @Before public void setUp() { MockitoAnnotations.initMocks(this); - Assert.sMainLooper = TestableLooper.get(this).getLooper(); + mTestableLooper = TestableLooper.get(this); + Assert.sMainLooper = mTestableLooper.getLooper(); + mHandler = Handler.createAsync(mTestableLooper.getLooper()); + mDependency.injectTestDependency(NotificationEntryManager.class, mEntryManager); mDependency.injectTestDependency(NotificationLockscreenUserManager.class, mLockscreenUserManager); @@ -97,7 +107,7 @@ public class NotificationViewHierarchyManagerTest extends SysuiTestCase { when(mEntryManager.getNotificationData()).thenReturn(mNotificationData); mViewHierarchyManager = new NotificationViewHierarchyManager(mContext, - mLockscreenUserManager, mGroupManager, mVisualStabilityManager, + mHandler, mLockscreenUserManager, mGroupManager, mVisualStabilityManager, mock(StatusBarStateControllerImpl.class), mEntryManager, () -> mShadeController, new BubbleData(mContext), mock(DynamicPrivacyController.class)); Dependency.get(InitController.class).executePostInitTasks(); @@ -212,9 +222,60 @@ public class NotificationViewHierarchyManagerTest extends SysuiTestCase { verify(entry0.getRow(), times(1)).showAppOpsIcons(any()); } + @Test + public void testReentrantCallsToOnDynamicPrivacyChangedPostForLater() { + // GIVEN a ListContainer that will make a re-entrant call to updateNotificationViews() + mMadeReentrantCall = false; + doAnswer((invocation) -> { + if (!mMadeReentrantCall) { + mMadeReentrantCall = true; + mViewHierarchyManager.onDynamicPrivacyChanged(); + } + return null; + }).when(mListContainer).setMaxDisplayedNotifications(anyInt()); + + // WHEN we call updateNotificationViews() + mViewHierarchyManager.updateNotificationViews(); + + // THEN onNotificationViewUpdateFinished() is only called once + verify(mListContainer).onNotificationViewUpdateFinished(); + + // WHEN we drain the looper + mTestableLooper.processAllMessages(); + + // THEN updateNotificationViews() is called a second time (for the reentrant call) + verify(mListContainer, times(2)).onNotificationViewUpdateFinished(); + } + + @Test + public void testMultipleReentrantCallsToOnDynamicPrivacyChangedOnlyPostOnce() { + // GIVEN a ListContainer that will make many re-entrant calls to updateNotificationViews() + mMadeReentrantCall = false; + doAnswer((invocation) -> { + if (!mMadeReentrantCall) { + mMadeReentrantCall = true; + mViewHierarchyManager.onDynamicPrivacyChanged(); + mViewHierarchyManager.onDynamicPrivacyChanged(); + mViewHierarchyManager.onDynamicPrivacyChanged(); + mViewHierarchyManager.onDynamicPrivacyChanged(); + } + return null; + }).when(mListContainer).setMaxDisplayedNotifications(anyInt()); + + // WHEN we call updateNotificationViews() and drain the looper + mViewHierarchyManager.updateNotificationViews(); + verify(mListContainer).onNotificationViewUpdateFinished(); + clearInvocations(mListContainer); + mTestableLooper.processAllMessages(); + + // THEN updateNotificationViews() is called only one more time + verify(mListContainer).onNotificationViewUpdateFinished(); + } + private class FakeListContainer implements NotificationListContainer { final LinearLayout mLayout = new LinearLayout(mContext); final List<View> mRows = Lists.newArrayList(); + private boolean mMakeReentrantCallDuringSetMaxDisplayedNotifications; @Override public void setChildTransferInProgress(boolean childTransferInProgress) {} @@ -263,7 +324,11 @@ public class NotificationViewHierarchyManagerTest extends SysuiTestCase { } @Override - public void setMaxDisplayedNotifications(int maxNotifications) {} + public void setMaxDisplayedNotifications(int maxNotifications) { + if (mMakeReentrantCallDuringSetMaxDisplayedNotifications) { + mViewHierarchyManager.onDynamicPrivacyChanged(); + } + } @Override public ViewGroup getViewParentForNotification(NotificationEntry entry) { @@ -298,5 +363,7 @@ public class NotificationViewHierarchyManagerTest extends SysuiTestCase { return false; } + @Override + public void onNotificationViewUpdateFinished() { } } } diff --git a/services/core/java/com/android/server/wm/DragState.java b/services/core/java/com/android/server/wm/DragState.java index 6127303141f4..553b0ffa6999 100644 --- a/services/core/java/com/android/server/wm/DragState.java +++ b/services/core/java/com/android/server/wm/DragState.java @@ -176,6 +176,8 @@ class DragState { mTransaction.transferTouchFocus(mTransferTouchFromToken, h.token); mTransferTouchFromToken = null; + // syncInputWindows here to ensure the input channel isn't removed before the transfer. + mTransaction.syncInputWindows(); mTransaction.apply(); } |