Revert "Fix 'No Apps' UI issues of ManageApplications"

This reverts commit 4a97095e364f279194af6b7d5721e8892ae12cf9.

Reason for revert: <It has abnormal scroll behavior when there is no profile tab>

Bug: 191945032
Bug: 191944934
Change-Id: Id6c71fbec4f490034bc07f6d8c9efabcb877d110
diff --git a/res/layout/manage_applications_apps.xml b/res/layout/manage_applications_apps.xml
index 055e4b4..d814164 100644
--- a/res/layout/manage_applications_apps.xml
+++ b/res/layout/manage_applications_apps.xml
@@ -14,7 +14,7 @@
      limitations under the License.
 -->
 
-<androidx.constraintlayout.widget.ConstraintLayout
+<FrameLayout
     xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:settings="http://schemas.android.com/apk/res-auto"
     android:layout_width="match_parent"
@@ -24,39 +24,40 @@
         android:id="@+id/pinned_header"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
-        android:elevation="2dp"
-        settings:layout_constraintTop_toTopOf="parent"/>
+        android:elevation="2dp"/>
 
-    <androidx.recyclerview.widget.RecyclerView
-        android:id="@+id/apps_list"
+    <FrameLayout
+        android:id="@+id/list_container"
         android:layout_width="match_parent"
-        android:layout_height="0dp"
-        android:clipToPadding="false"
-        android:scrollbars="none"
-        android:visibility="invisible"
-        settings:fastScrollEnabled="true"
-        settings:fastScrollHorizontalThumbDrawable="@drawable/thumb_drawable"
-        settings:fastScrollHorizontalTrackDrawable="@drawable/line_drawable"
-        settings:fastScrollVerticalThumbDrawable="@drawable/thumb_drawable"
-        settings:fastScrollVerticalTrackDrawable="@drawable/line_drawable"
-        settings:layout_constraintTop_toBottomOf="@id/pinned_header"
-        settings:layout_constraintBottom_toBottomOf="parent"/>
+        android:layout_height="match_parent"
+        android:visibility="gone">
 
-    <TextView
-        android:id="@android:id/empty"
-        android:layout_width="match_parent"
-        android:layout_height="0dp"
-        android:gravity="center"
-        android:text="@string/no_applications"
-        android:textAppearance="?android:attr/textAppearanceLarge"
-        android:visibility="invisible"
-        settings:layout_constraintTop_toTopOf="parent"
-        settings:layout_constraintBottom_toBottomOf="parent"/>
+        <androidx.recyclerview.widget.RecyclerView
+            android:id="@+id/apps_list"
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            android:clipToPadding="false"
+            android:scrollbars="none"
+            settings:fastScrollEnabled="true"
+            settings:fastScrollHorizontalThumbDrawable="@drawable/thumb_drawable"
+            settings:fastScrollHorizontalTrackDrawable="@drawable/line_drawable"
+            settings:fastScrollVerticalThumbDrawable="@drawable/thumb_drawable"
+            settings:fastScrollVerticalTrackDrawable="@drawable/line_drawable"/>
 
-    <include layout="@layout/loading_container"
-        settings:layout_constraintTop_toBottomOf="@id/pinned_header"
-        settings:layout_constraintBottom_toBottomOf="parent"/>
+        <TextView
+            android:id="@android:id/empty"
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            android:gravity="bottom|center_horizontal"
+            android:layout_gravity="center"
+            android:text="@string/no_applications"
+            android:textAppearance="?android:attr/textAppearanceLarge"
+            android:visibility="invisible"/>
 
-</androidx.constraintlayout.widget.ConstraintLayout>
+    </FrameLayout>
+
+    <include layout="@layout/loading_container"/>
+
+</FrameLayout>
 
 
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index b1f5b30..eb0d46b 100755
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -149,6 +149,8 @@
     <dimen name="wifi_assistant_height">182dp</dimen>
     <dimen name="wifi_assistant_image_top">32dp</dimen>
     <dimen name="wifi_assistant_image_start">24dp</dimen>
+    <!-- appbar height is equal search bar height (48dp) plus search bar top and bottom margin  -->
+    <dimen name="app_bar_height">80dp</dimen>
 
     <!-- CryptKeeper top margin for password/pin screen -->
     <dimen name="crypt_keeper_password_top_margin">88dip</dimen>
diff --git a/src/com/android/settings/applications/RunningServices.java b/src/com/android/settings/applications/RunningServices.java
index b1689d5..4d13241 100644
--- a/src/com/android/settings/applications/RunningServices.java
+++ b/src/com/android/settings/applications/RunningServices.java
@@ -72,11 +72,7 @@
     public void onResume() {
         super.onResume();
         boolean haveData = mRunningProcessesView.doResume(this, mRunningProcessesAvail);
-        if (haveData) {
-            mLoadingViewController.showContent(false /* animate */);
-        } else {
-            mLoadingViewController.showLoadingView();
-        }
+        mLoadingViewController.handleLoadingContainer(haveData /* done */, false /* animate */);
     }
 
     @Override
diff --git a/src/com/android/settings/applications/manageapplications/ManageApplications.java b/src/com/android/settings/applications/manageapplications/ManageApplications.java
index 43e929b..6d67524 100644
--- a/src/com/android/settings/applications/manageapplications/ManageApplications.java
+++ b/src/com/android/settings/applications/manageapplications/ManageApplications.java
@@ -208,6 +208,7 @@
     private ApplicationsAdapter mApplications;
 
     private View mLoadingContainer;
+    private View mListContainer;
     private SearchView mSearchView;
 
     // Size resource used for packages whose size computation failed for some reason
@@ -401,21 +402,25 @@
 
         mRootView = inflater.inflate(R.layout.manage_applications_apps, null);
         mLoadingContainer = mRootView.findViewById(R.id.loading_container);
-        mEmptyView = mRootView.findViewById(android.R.id.empty);
-        mRecyclerView = mRootView.findViewById(R.id.apps_list);
+        mListContainer = mRootView.findViewById(R.id.list_container);
+        if (mListContainer != null) {
+            // Create adapter and list view here
+            mEmptyView = mListContainer.findViewById(android.R.id.empty);
 
-        mApplications = new ApplicationsAdapter(mApplicationsState, this, mFilter,
-                savedInstanceState);
-        if (savedInstanceState != null) {
-            mApplications.mHasReceivedLoadEntries =
-                    savedInstanceState.getBoolean(EXTRA_HAS_ENTRIES, false);
-            mApplications.mHasReceivedBridgeCallback =
-                    savedInstanceState.getBoolean(EXTRA_HAS_BRIDGE, false);
+            mApplications = new ApplicationsAdapter(mApplicationsState, this, mFilter,
+                    savedInstanceState);
+            if (savedInstanceState != null) {
+                mApplications.mHasReceivedLoadEntries =
+                        savedInstanceState.getBoolean(EXTRA_HAS_ENTRIES, false);
+                mApplications.mHasReceivedBridgeCallback =
+                        savedInstanceState.getBoolean(EXTRA_HAS_BRIDGE, false);
+            }
+            mRecyclerView = mListContainer.findViewById(R.id.apps_list);
+            mRecyclerView.setItemAnimator(null);
+            mRecyclerView.setLayoutManager(new LinearLayoutManager(
+                    getContext(), RecyclerView.VERTICAL, false /* reverseLayout */));
+            mRecyclerView.setAdapter(mApplications);
         }
-        mRecyclerView.setItemAnimator(null);
-        mRecyclerView.setLayoutManager(new LinearLayoutManager(
-                getContext(), RecyclerView.VERTICAL, false /* reverseLayout */));
-        mRecyclerView.setAdapter(mApplications);
 
         // We have to do this now because PreferenceFrameLayout looks at it
         // only when the view is added.
@@ -980,8 +985,16 @@
             // overlapped by floating filter.
             if (hasFilter) {
                 mManageApplications.mSpinnerHeader.setVisibility(View.VISIBLE);
+                mManageApplications.mRecyclerView.setPadding(0 /* left */,
+                        mContext.getResources().getDimensionPixelSize(
+                                R.dimen.app_bar_height) /* top */,
+                        0 /* right */,
+                        0 /* bottom */);
             } else {
                 mManageApplications.mSpinnerHeader.setVisibility(View.GONE);
+                mManageApplications.mRecyclerView.setPadding(0 /* left */, 0 /* top */,
+                        0 /* right */,
+                        0 /* bottom */);
             }
         }
     }
@@ -1031,8 +1044,7 @@
             mManageApplications = manageApplications;
             mLoadingViewController = new LoadingViewController(
                     mManageApplications.mLoadingContainer,
-                    mManageApplications.mRecyclerView,
-                    mManageApplications.mEmptyView
+                    mManageApplications.mListContainer
             );
             mContext = manageApplications.getActivity();
             mIconDrawableFactory = IconDrawableFactory.newInstance(mContext);
@@ -1291,9 +1303,11 @@
             mOriginalEntries = entries;
             notifyDataSetChanged();
             if (getItemCount() == 0) {
-                mLoadingViewController.showEmpty(false /* animate */);
+                mManageApplications.mRecyclerView.setVisibility(View.GONE);
+                mManageApplications.mEmptyView.setVisibility(View.VISIBLE);
             } else {
-                mLoadingViewController.showContent(false /* animate */);
+                mManageApplications.mEmptyView.setVisibility(View.GONE);
+                mManageApplications.mRecyclerView.setVisibility(View.VISIBLE);
 
                 if (mManageApplications.mSearchView != null
                         && mManageApplications.mSearchView.isVisibleToUser()) {
@@ -1310,6 +1324,10 @@
                 mLastIndex = -1;
             }
 
+            if (mSession.getAllApps().size() != 0
+                    && mManageApplications.mListContainer.getVisibility() != View.VISIBLE) {
+                mLoadingViewController.showContent(true /* animate */);
+            }
             if (mManageApplications.mListType == LIST_TYPE_USAGE_ACCESS) {
                 // No enabled or disabled filters for usage access.
                 return;
diff --git a/src/com/android/settings/widget/LoadingViewController.java b/src/com/android/settings/widget/LoadingViewController.java
index 66eebf3..294e55e 100644
--- a/src/com/android/settings/widget/LoadingViewController.java
+++ b/src/com/android/settings/widget/LoadingViewController.java
@@ -22,66 +22,34 @@
 import android.view.animation.Animation;
 import android.view.animation.AnimationUtils;
 
-import androidx.annotation.Nullable;
-
 /**
- * A helper class that manages show/hide loading spinner, content view and empty view (optional).
+ * A helper class that manages show/hide loading spinner.
  */
 public class LoadingViewController {
 
     private static final long DELAY_SHOW_LOADING_CONTAINER_THRESHOLD_MS = 100L;
 
-    private final Handler mFgHandler;
-    private final View mLoadingView;
-    private final View mContentView;
-    private final View mEmptyView;
+    public final Handler mFgHandler;
+    public final View mLoadingView;
+    public final View mContentView;
 
     public LoadingViewController(View loadingView, View contentView) {
-        this(loadingView, contentView, null /* emptyView*/);
-    }
-
-    public LoadingViewController(View loadingView, View contentView, @Nullable View emptyView) {
         mLoadingView = loadingView;
         mContentView = contentView;
-        mEmptyView = emptyView;
         mFgHandler = new Handler(Looper.getMainLooper());
     }
 
     private Runnable mShowLoadingContainerRunnable = new Runnable() {
         public void run() {
-            showLoadingView();
+            handleLoadingContainer(false /* done */, false /* animate */);
         }
     };
 
-    /**
-     *  Shows content view and hides loading view & empty view.
-     */
     public void showContent(boolean animate) {
         // Cancel any pending task to show the loading animation and show the list of
         // apps directly.
         mFgHandler.removeCallbacks(mShowLoadingContainerRunnable);
-        handleLoadingContainer(true /* showContent */, false /* showEmpty*/, animate);
-    }
-
-    /**
-     *  Shows empty view and hides loading view & content view.
-     */
-    public void showEmpty(boolean animate) {
-        if (mEmptyView == null) {
-            return;
-        }
-
-        // Cancel any pending task to show the loading animation and show the list of
-        // apps directly.
-        mFgHandler.removeCallbacks(mShowLoadingContainerRunnable);
-        handleLoadingContainer(false /* showContent */, true /* showEmpty */, animate);
-    }
-
-    /**
-     *  Shows loading view and hides content view & empty view.
-     */
-    public void showLoadingView() {
-        handleLoadingContainer(false /* showContent */, false /* showEmpty */, false /* animate */);
+        handleLoadingContainer(true /* show */, animate);
     }
 
     public void showLoadingViewDelayed() {
@@ -89,9 +57,8 @@
                 mShowLoadingContainerRunnable, DELAY_SHOW_LOADING_CONTAINER_THRESHOLD_MS);
     }
 
-    private void handleLoadingContainer(boolean showContent, boolean showEmpty, boolean animate) {
-        handleLoadingContainer(mLoadingView, mContentView, mEmptyView,
-                showContent, showEmpty, animate);
+    public void handleLoadingContainer(boolean done, boolean animate) {
+        handleLoadingContainer(mLoadingView, mContentView, done, animate);
     }
 
     /**
@@ -108,25 +75,6 @@
         setViewShown(content, done, animate);
     }
 
-    /**
-     * Show/hide loading view and content view and empty view.
-     *
-     * @param loading The loading spinner view
-     * @param content The content view
-     * @param empty The empty view shows no item summary to users.
-     * @param showContent    If true, content is set visible and loading is set invisible.
-     * @param showEmpty    If true, empty is set visible and loading is set invisible.
-     * @param animate Whether or not content/loading views should animate in/out.
-     */
-    public static void handleLoadingContainer(View loading, View content, View empty,
-            boolean showContent, boolean showEmpty, boolean animate) {
-        if (empty != null) {
-            setViewShown(empty, showEmpty, animate);
-        }
-        setViewShown(content, showContent, animate);
-        setViewShown(loading, !showContent && !showEmpty, animate);
-    }
-
     private static void setViewShown(final View view, boolean shown, boolean animate) {
         if (animate) {
             Animation animation = AnimationUtils.loadAnimation(view.getContext(),
diff --git a/tests/robotests/src/com/android/settings/applications/manageapplications/ManageApplicationsTest.java b/tests/robotests/src/com/android/settings/applications/manageapplications/ManageApplicationsTest.java
index 25eca7a..86f5fe8 100644
--- a/tests/robotests/src/com/android/settings/applications/manageapplications/ManageApplicationsTest.java
+++ b/tests/robotests/src/com/android/settings/applications/manageapplications/ManageApplicationsTest.java
@@ -28,6 +28,7 @@
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyBoolean;
 import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.doNothing;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.mock;
@@ -48,6 +49,7 @@
 import android.view.MenuInflater;
 import android.view.MenuItem;
 import android.view.View;
+import android.view.ViewGroup;
 import android.widget.SearchView;
 
 import androidx.fragment.app.FragmentActivity;
@@ -154,6 +156,22 @@
     }
 
     @Test
+    public void onCreateView_shouldNotShowLoadingContainer() {
+        ReflectionHelpers.setField(mFragment, "mResetAppsHelper", mock(ResetAppsHelper.class));
+        doNothing().when(mFragment).createHeader();
+
+        final LayoutInflater layoutInflater = mock(LayoutInflater.class);
+        final View view = mock(View.class);
+        final View loadingContainer = mock(View.class);
+        when(layoutInflater.inflate(anyInt(), eq(null))).thenReturn(view);
+        when(view.findViewById(R.id.loading_container)).thenReturn(loadingContainer);
+
+        mFragment.onCreateView(layoutInflater, mock(ViewGroup.class), null);
+
+        verify(loadingContainer, never()).setVisibility(View.VISIBLE);
+    }
+
+    @Test
     public void onCreateOptionsMenu_shouldSetSearchQueryListener() {
         final SearchView searchView = mock(SearchView.class);
         final MenuItem searchMenu = mock(MenuItem.class);
@@ -203,6 +221,7 @@
     @Test
     public void updateLoading_appLoaded_shouldNotDelayCallToHandleLoadingContainer() {
         ReflectionHelpers.setField(mFragment, "mLoadingContainer", mock(View.class));
+        ReflectionHelpers.setField(mFragment, "mListContainer", mock(View.class));
         final ManageApplications.ApplicationsAdapter adapter =
                 spy(new ManageApplications.ApplicationsAdapter(mState, mFragment,
                         AppFilterRegistry.getInstance().get(FILTER_APPS_ALL), new Bundle()));
@@ -224,6 +243,7 @@
     @Test
     public void updateLoading_appNotLoaded_shouldDelayCallToHandleLoadingContainer() {
         ReflectionHelpers.setField(mFragment, "mLoadingContainer", mock(View.class));
+        ReflectionHelpers.setField(mFragment, "mListContainer", mock(View.class));
         final ManageApplications.ApplicationsAdapter adapter =
                 spy(new ManageApplications.ApplicationsAdapter(mState, mFragment,
                         AppFilterRegistry.getInstance().get(FILTER_APPS_ALL), new Bundle()));
@@ -252,6 +272,7 @@
         when(listContainer.getVisibility()).thenReturn(View.INVISIBLE);
         when(listContainer.getContext()).thenReturn(context);
         ReflectionHelpers.setField(mFragment, "mLoadingContainer", loadingContainer);
+        ReflectionHelpers.setField(mFragment, "mListContainer", listContainer);
         final ManageApplications.ApplicationsAdapter adapter =
                 spy(new ManageApplications.ApplicationsAdapter(mState, mFragment,
                         AppFilterRegistry.getInstance().get(FILTER_APPS_ALL), new Bundle()));
@@ -275,7 +296,7 @@
 
         adapter.onRebuildComplete(null);
 
-        verify(loadingViewController).showEmpty(false /* animate */);
+        verify(loadingViewController).showContent(true /* animate */);
     }
 
     @Test
@@ -283,16 +304,15 @@
         final String query = "Test";
         final RecyclerView recyclerView = mock(RecyclerView.class);
         final View emptyView = mock(View.class);
-        final View loadingContainer = mock(View.class);
         ReflectionHelpers.setField(mFragment, "mRecyclerView", recyclerView);
         ReflectionHelpers.setField(mFragment, "mEmptyView", emptyView);
-        ReflectionHelpers.setField(mFragment, "mLoadingContainer", loadingContainer);
         final SearchView searchView = mock(SearchView.class);
         ReflectionHelpers.setField(mFragment, "mSearchView", searchView);
         when(searchView.isVisibleToUser()).thenReturn(true);
         when(searchView.getQuery()).thenReturn(query);
         final View listContainer = mock(View.class);
         when(listContainer.getVisibility()).thenReturn(View.VISIBLE);
+        ReflectionHelpers.setField(mFragment, "mListContainer", listContainer);
         ReflectionHelpers.setField(
                 mFragment, "mFilterAdapter", mock(ManageApplications.FilterSpinnerAdapter.class));
         final ArrayList<ApplicationsState.AppEntry> appList = new ArrayList<>();
@@ -471,6 +491,8 @@
         mFragment.mFilterAdapter.updateFilterView(true);
 
         assertThat(mFragment.mSpinnerHeader.getVisibility()).isEqualTo(View.VISIBLE);
+        assertThat(mFragment.mRecyclerView.getPaddingTop()).isEqualTo(
+                mContext.getResources().getDimensionPixelSize(R.dimen.app_bar_height));
     }
 
     @Test