Loading src/com/android/settings/panel/PanelFragment.java +9 −0 Original line number Diff line number Diff line Loading @@ -98,6 +98,7 @@ public class PanelFragment extends Fragment { private TextView mHeaderSubtitle; private int mMaxHeight; private View mFooterDivider; private boolean mPanelCreating; private final Map<Uri, LiveData<Slice>> mSliceLiveData = new LinkedHashMap<>(); Loading Loading @@ -128,6 +129,7 @@ public class PanelFragment extends Fragment { if (mPanelSlices != null) { mPanelSlices.getViewTreeObserver().removeOnGlobalLayoutListener(this); } mPanelCreating = false; } }; Loading @@ -141,6 +143,7 @@ public class PanelFragment extends Fragment { mLayoutView.getViewTreeObserver() .addOnGlobalLayoutListener(mPanelLayoutListener); mMaxHeight = getResources().getDimensionPixelSize(R.dimen.output_switcher_slice_max_height); mPanelCreating = true; createPanelContent(); return mLayoutView; } Loading @@ -154,6 +157,7 @@ public class PanelFragment extends Fragment { * Call createPanelContent() once animation end. */ void updatePanelWithAnimation() { mPanelCreating = true; final View panelContent = mLayoutView.findViewById(R.id.panel_container); final AnimatorSet animatorSet = buildAnimatorSet(mLayoutView, 0.0f /* startY */, panelContent.getHeight() /* endY */, Loading @@ -172,11 +176,16 @@ public class PanelFragment extends Fragment { animatorSet.start(); } boolean isPanelCreating() { return mPanelCreating; } private void createPanelContent() { final FragmentActivity activity = getActivity(); if (mLayoutView == null) { activity.finish(); } final ViewGroup.LayoutParams params = mLayoutView.getLayoutParams(); params.height = ViewGroup.LayoutParams.WRAP_CONTENT; mLayoutView.setLayoutParams(params); Loading src/com/android/settings/panel/SettingsPanelActivity.java +27 −10 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ import static com.android.settingslib.media.MediaOutputSliceConstants.EXTRA_PACK import android.content.Intent; import android.content.res.Configuration; import android.os.Bundle; import android.text.TextUtils; import android.util.Log; import android.view.Gravity; import android.view.Window; Loading @@ -41,12 +42,14 @@ import com.android.settings.core.HideNonSystemOverlayMixin; */ public class SettingsPanelActivity extends FragmentActivity { private final String TAG = "panel_activity"; private static final String TAG = "SettingsPanelActivity"; @VisibleForTesting final Bundle mBundle = new Bundle(); @VisibleForTesting boolean mForceCreation = false; @VisibleForTesting PanelFragment mPanelFragment; /** * Key specifying which Panel the app is requesting. Loading Loading @@ -87,8 +90,10 @@ public class SettingsPanelActivity extends FragmentActivity { @Override protected void onStop() { super.onStop(); if (mPanelFragment != null && !mPanelFragment.isPanelCreating()) { mForceCreation = true; } } @Override public void onConfigurationChanged(@NonNull Configuration newConfig) { Loading @@ -104,10 +109,10 @@ public class SettingsPanelActivity extends FragmentActivity { return; } final String action = callingIntent.getAction(); // We will use it once media output switch panel support remote device. final String mediaPackageName = callingIntent.getStringExtra(EXTRA_PACKAGE_NAME); mBundle.putString(KEY_PANEL_TYPE_ARGUMENT, callingIntent.getAction()); mBundle.putString(KEY_PANEL_TYPE_ARGUMENT, action); mBundle.putString(KEY_CALLING_PACKAGE_NAME, getCallingPackage()); mBundle.putString(KEY_MEDIA_PACKAGE_NAME, mediaPackageName); Loading @@ -116,9 +121,21 @@ public class SettingsPanelActivity extends FragmentActivity { // If fragment already exists and visible, we will need to update panel with animation. if (!shouldForceCreation && fragment != null && fragment instanceof PanelFragment) { final PanelFragment panelFragment = (PanelFragment) fragment; panelFragment.setArguments(mBundle); panelFragment.updatePanelWithAnimation(); mPanelFragment = (PanelFragment) fragment; if (mPanelFragment.isPanelCreating()) { Log.w(TAG, "A panel is creating, skip " + action); return; } final Bundle bundle = fragment.getArguments(); if (bundle != null && TextUtils.equals(action, bundle.getString(KEY_PANEL_TYPE_ARGUMENT))) { Log.w(TAG, "Panel is showing the same action, skip " + action); return; } mPanelFragment.setArguments(new Bundle(mBundle)); mPanelFragment.updatePanelWithAnimation(); } else { setContentView(R.layout.settings_panel); Loading @@ -127,9 +144,9 @@ public class SettingsPanelActivity extends FragmentActivity { window.setGravity(Gravity.BOTTOM); window.setLayout(WindowManager.LayoutParams.MATCH_PARENT, WindowManager.LayoutParams.WRAP_CONTENT); final PanelFragment panelFragment = new PanelFragment(); panelFragment.setArguments(mBundle); fragmentManager.beginTransaction().add(R.id.main_content, panelFragment).commit(); mPanelFragment = new PanelFragment(); mPanelFragment.setArguments(new Bundle(mBundle)); fragmentManager.beginTransaction().add(R.id.main_content, mPanelFragment).commit(); } } } tests/robotests/src/com/android/settings/panel/SettingsPanelActivityTest.java +64 −0 Original line number Diff line number Diff line Loading @@ -26,6 +26,7 @@ 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.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; Loading @@ -36,6 +37,9 @@ import android.os.Build; import android.view.Window; import android.view.WindowManager; import androidx.fragment.app.FragmentManager; import com.android.settings.R; import com.android.settings.core.HideNonSystemOverlayMixin; import com.android.settings.testutils.FakeFeatureFactory; Loading @@ -43,6 +47,7 @@ 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.Robolectric; import org.robolectric.RobolectricTestRunner; Loading @@ -56,6 +61,10 @@ public class SettingsPanelActivityTest { private FakeSettingsPanelActivity mSettingsPanelActivity; private PanelFeatureProvider mPanelFeatureProvider; private FakePanelContent mFakePanelContent; @Mock private PanelFragment mPanelFragment; @Mock private FragmentManager mFragmentManager; @Before public void setUp() { Loading @@ -67,6 +76,10 @@ public class SettingsPanelActivityTest { mFakeFeatureFactory.panelFeatureProvider = mPanelFeatureProvider; mFakePanelContent = new FakePanelContent(); doReturn(mFakePanelContent).when(mPanelFeatureProvider).getPanel(any(), any()); mSettingsPanelActivity.mPanelFragment = mPanelFragment; when(mFragmentManager.findFragmentById(R.id.main_content)).thenReturn(mPanelFragment); when(mSettingsPanelActivity.getSupportFragmentManager()).thenReturn(mFragmentManager); } @Test Loading Loading @@ -141,11 +154,62 @@ public class SettingsPanelActivityTest { & SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS).isEqualTo(0); } @Test public void onStop_panelIsNotCreating_shouldForceUpdate() { mSettingsPanelActivity.mForceCreation = false; when(mPanelFragment.isPanelCreating()).thenReturn(false); mSettingsPanelActivity.mPanelFragment = mPanelFragment; mSettingsPanelActivity.onStop(); assertThat(mSettingsPanelActivity.mForceCreation).isTrue(); } @Test public void onStop_panelIsCreating_shouldNotForceUpdate() { mSettingsPanelActivity.mForceCreation = false; when(mPanelFragment.isPanelCreating()).thenReturn(true); mSettingsPanelActivity.mPanelFragment = mPanelFragment; mSettingsPanelActivity.onStop(); assertThat(mSettingsPanelActivity.mForceCreation).isFalse(); } @Test public void onConfigurationChanged_shouldForceUpdate() { mSettingsPanelActivity.mForceCreation = false; mSettingsPanelActivity.onConfigurationChanged(new Configuration()); assertThat(mSettingsPanelActivity.mForceCreation).isTrue(); } @Test public void onNewIntent_panelIsNotCreating_shouldUpdatePanel() { when(mPanelFragment.isPanelCreating()).thenReturn(false); mSettingsPanelActivity.onNewIntent(mSettingsPanelActivity.getIntent()); verify(mPanelFragment).updatePanelWithAnimation(); } @Test public void onNewIntent_panelIsCreating_shouldNotUpdatePanel() { when(mPanelFragment.isPanelCreating()).thenReturn(true); mSettingsPanelActivity.onNewIntent(mSettingsPanelActivity.getIntent()); verify(mPanelFragment, never()).updatePanelWithAnimation(); } @Test public void onNewIntent_panelIsShowingTheSameAction_shouldNotUpdatePanel() { when(mPanelFragment.isPanelCreating()).thenReturn(false); when(mPanelFragment.getArguments()).thenReturn(mSettingsPanelActivity.mBundle); mSettingsPanelActivity.onNewIntent(mSettingsPanelActivity.getIntent()); verify(mPanelFragment, never()).updatePanelWithAnimation(); } } Loading
src/com/android/settings/panel/PanelFragment.java +9 −0 Original line number Diff line number Diff line Loading @@ -98,6 +98,7 @@ public class PanelFragment extends Fragment { private TextView mHeaderSubtitle; private int mMaxHeight; private View mFooterDivider; private boolean mPanelCreating; private final Map<Uri, LiveData<Slice>> mSliceLiveData = new LinkedHashMap<>(); Loading Loading @@ -128,6 +129,7 @@ public class PanelFragment extends Fragment { if (mPanelSlices != null) { mPanelSlices.getViewTreeObserver().removeOnGlobalLayoutListener(this); } mPanelCreating = false; } }; Loading @@ -141,6 +143,7 @@ public class PanelFragment extends Fragment { mLayoutView.getViewTreeObserver() .addOnGlobalLayoutListener(mPanelLayoutListener); mMaxHeight = getResources().getDimensionPixelSize(R.dimen.output_switcher_slice_max_height); mPanelCreating = true; createPanelContent(); return mLayoutView; } Loading @@ -154,6 +157,7 @@ public class PanelFragment extends Fragment { * Call createPanelContent() once animation end. */ void updatePanelWithAnimation() { mPanelCreating = true; final View panelContent = mLayoutView.findViewById(R.id.panel_container); final AnimatorSet animatorSet = buildAnimatorSet(mLayoutView, 0.0f /* startY */, panelContent.getHeight() /* endY */, Loading @@ -172,11 +176,16 @@ public class PanelFragment extends Fragment { animatorSet.start(); } boolean isPanelCreating() { return mPanelCreating; } private void createPanelContent() { final FragmentActivity activity = getActivity(); if (mLayoutView == null) { activity.finish(); } final ViewGroup.LayoutParams params = mLayoutView.getLayoutParams(); params.height = ViewGroup.LayoutParams.WRAP_CONTENT; mLayoutView.setLayoutParams(params); Loading
src/com/android/settings/panel/SettingsPanelActivity.java +27 −10 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ import static com.android.settingslib.media.MediaOutputSliceConstants.EXTRA_PACK import android.content.Intent; import android.content.res.Configuration; import android.os.Bundle; import android.text.TextUtils; import android.util.Log; import android.view.Gravity; import android.view.Window; Loading @@ -41,12 +42,14 @@ import com.android.settings.core.HideNonSystemOverlayMixin; */ public class SettingsPanelActivity extends FragmentActivity { private final String TAG = "panel_activity"; private static final String TAG = "SettingsPanelActivity"; @VisibleForTesting final Bundle mBundle = new Bundle(); @VisibleForTesting boolean mForceCreation = false; @VisibleForTesting PanelFragment mPanelFragment; /** * Key specifying which Panel the app is requesting. Loading Loading @@ -87,8 +90,10 @@ public class SettingsPanelActivity extends FragmentActivity { @Override protected void onStop() { super.onStop(); if (mPanelFragment != null && !mPanelFragment.isPanelCreating()) { mForceCreation = true; } } @Override public void onConfigurationChanged(@NonNull Configuration newConfig) { Loading @@ -104,10 +109,10 @@ public class SettingsPanelActivity extends FragmentActivity { return; } final String action = callingIntent.getAction(); // We will use it once media output switch panel support remote device. final String mediaPackageName = callingIntent.getStringExtra(EXTRA_PACKAGE_NAME); mBundle.putString(KEY_PANEL_TYPE_ARGUMENT, callingIntent.getAction()); mBundle.putString(KEY_PANEL_TYPE_ARGUMENT, action); mBundle.putString(KEY_CALLING_PACKAGE_NAME, getCallingPackage()); mBundle.putString(KEY_MEDIA_PACKAGE_NAME, mediaPackageName); Loading @@ -116,9 +121,21 @@ public class SettingsPanelActivity extends FragmentActivity { // If fragment already exists and visible, we will need to update panel with animation. if (!shouldForceCreation && fragment != null && fragment instanceof PanelFragment) { final PanelFragment panelFragment = (PanelFragment) fragment; panelFragment.setArguments(mBundle); panelFragment.updatePanelWithAnimation(); mPanelFragment = (PanelFragment) fragment; if (mPanelFragment.isPanelCreating()) { Log.w(TAG, "A panel is creating, skip " + action); return; } final Bundle bundle = fragment.getArguments(); if (bundle != null && TextUtils.equals(action, bundle.getString(KEY_PANEL_TYPE_ARGUMENT))) { Log.w(TAG, "Panel is showing the same action, skip " + action); return; } mPanelFragment.setArguments(new Bundle(mBundle)); mPanelFragment.updatePanelWithAnimation(); } else { setContentView(R.layout.settings_panel); Loading @@ -127,9 +144,9 @@ public class SettingsPanelActivity extends FragmentActivity { window.setGravity(Gravity.BOTTOM); window.setLayout(WindowManager.LayoutParams.MATCH_PARENT, WindowManager.LayoutParams.WRAP_CONTENT); final PanelFragment panelFragment = new PanelFragment(); panelFragment.setArguments(mBundle); fragmentManager.beginTransaction().add(R.id.main_content, panelFragment).commit(); mPanelFragment = new PanelFragment(); mPanelFragment.setArguments(new Bundle(mBundle)); fragmentManager.beginTransaction().add(R.id.main_content, mPanelFragment).commit(); } } }
tests/robotests/src/com/android/settings/panel/SettingsPanelActivityTest.java +64 −0 Original line number Diff line number Diff line Loading @@ -26,6 +26,7 @@ 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.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; Loading @@ -36,6 +37,9 @@ import android.os.Build; import android.view.Window; import android.view.WindowManager; import androidx.fragment.app.FragmentManager; import com.android.settings.R; import com.android.settings.core.HideNonSystemOverlayMixin; import com.android.settings.testutils.FakeFeatureFactory; Loading @@ -43,6 +47,7 @@ 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.Robolectric; import org.robolectric.RobolectricTestRunner; Loading @@ -56,6 +61,10 @@ public class SettingsPanelActivityTest { private FakeSettingsPanelActivity mSettingsPanelActivity; private PanelFeatureProvider mPanelFeatureProvider; private FakePanelContent mFakePanelContent; @Mock private PanelFragment mPanelFragment; @Mock private FragmentManager mFragmentManager; @Before public void setUp() { Loading @@ -67,6 +76,10 @@ public class SettingsPanelActivityTest { mFakeFeatureFactory.panelFeatureProvider = mPanelFeatureProvider; mFakePanelContent = new FakePanelContent(); doReturn(mFakePanelContent).when(mPanelFeatureProvider).getPanel(any(), any()); mSettingsPanelActivity.mPanelFragment = mPanelFragment; when(mFragmentManager.findFragmentById(R.id.main_content)).thenReturn(mPanelFragment); when(mSettingsPanelActivity.getSupportFragmentManager()).thenReturn(mFragmentManager); } @Test Loading Loading @@ -141,11 +154,62 @@ public class SettingsPanelActivityTest { & SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS).isEqualTo(0); } @Test public void onStop_panelIsNotCreating_shouldForceUpdate() { mSettingsPanelActivity.mForceCreation = false; when(mPanelFragment.isPanelCreating()).thenReturn(false); mSettingsPanelActivity.mPanelFragment = mPanelFragment; mSettingsPanelActivity.onStop(); assertThat(mSettingsPanelActivity.mForceCreation).isTrue(); } @Test public void onStop_panelIsCreating_shouldNotForceUpdate() { mSettingsPanelActivity.mForceCreation = false; when(mPanelFragment.isPanelCreating()).thenReturn(true); mSettingsPanelActivity.mPanelFragment = mPanelFragment; mSettingsPanelActivity.onStop(); assertThat(mSettingsPanelActivity.mForceCreation).isFalse(); } @Test public void onConfigurationChanged_shouldForceUpdate() { mSettingsPanelActivity.mForceCreation = false; mSettingsPanelActivity.onConfigurationChanged(new Configuration()); assertThat(mSettingsPanelActivity.mForceCreation).isTrue(); } @Test public void onNewIntent_panelIsNotCreating_shouldUpdatePanel() { when(mPanelFragment.isPanelCreating()).thenReturn(false); mSettingsPanelActivity.onNewIntent(mSettingsPanelActivity.getIntent()); verify(mPanelFragment).updatePanelWithAnimation(); } @Test public void onNewIntent_panelIsCreating_shouldNotUpdatePanel() { when(mPanelFragment.isPanelCreating()).thenReturn(true); mSettingsPanelActivity.onNewIntent(mSettingsPanelActivity.getIntent()); verify(mPanelFragment, never()).updatePanelWithAnimation(); } @Test public void onNewIntent_panelIsShowingTheSameAction_shouldNotUpdatePanel() { when(mPanelFragment.isPanelCreating()).thenReturn(false); when(mPanelFragment.getArguments()).thenReturn(mSettingsPanelActivity.mBundle); mSettingsPanelActivity.onNewIntent(mSettingsPanelActivity.getIntent()); verify(mPanelFragment, never()).updatePanelWithAnimation(); } }