diff options
author | 2020-04-08 14:23:30 +0100 | |
---|---|---|
committer | 2020-04-14 16:42:37 +0100 | |
commit | 9d344de052c8a4a87986ca6597e2f8179c0b6829 (patch) | |
tree | 2f9c0d9c817803c3cbc34dde7e288c77a3689eb2 | |
parent | ec7315e0390971780eac1139fd8bfa7a152f2507 (diff) |
Show a spinner when user click on cross profile button
Bug: 151733420
Test: manual
Change-Id: Ide0d5b9f93117fd05ef87b5cf40b73433d80d42a
9 files changed, 210 insertions, 37 deletions
diff --git a/res/layout/item_doc_inflated_message_cross_profile.xml b/res/layout/item_doc_inflated_message_cross_profile.xml index eb9540d5e..337819a82 100644 --- a/res/layout/item_doc_inflated_message_cross_profile.xml +++ b/res/layout/item_doc_inflated_message_cross_profile.xml @@ -25,27 +25,44 @@ android:paddingStart="72dp" android:paddingEnd="72dp"> - <ImageView - android:id="@+id/artwork" - android:layout_width="24dp" - android:layout_height="24dp"/> - <TextView - android:id="@+id/title" - android:layout_marginTop="8dp" + <ProgressBar + android:id="@+id/cross_profile_progress" + style="@android:style/Widget.Material.Light.ProgressBar" + android:visibility="gone" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:textAppearance="@style/EmptyStateTitleText"/> - <TextView - android:id="@+id/message" - android:layout_marginTop="4dp" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:gravity="center_horizontal" - android:textAppearance="@style/EmptyStateMessageText"/> - <Button - android:id="@+id/button" - android:layout_marginTop="16dp" + android:indeterminate="true" + android:indeterminateTint="?attr/colorAccent"/> + + <LinearLayout + android:id="@+id/cross_profile_content" android:layout_width="wrap_content" android:layout_height="wrap_content" - style="@style/EmptyStateButton"/> -</LinearLayout>
\ No newline at end of file + android:orientation="vertical" + android:gravity="center_horizontal"> + + <ImageView + android:id="@+id/artwork" + android:layout_width="24dp" + android:layout_height="24dp"/> + <TextView + android:id="@+id/title" + android:layout_marginTop="8dp" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:textAppearance="@style/EmptyStateTitleText"/> + <TextView + android:id="@+id/message" + android:layout_marginTop="4dp" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:gravity="center_horizontal" + android:textAppearance="@style/EmptyStateMessageText"/> + <Button + android:id="@+id/button" + android:layout_marginTop="16dp" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + style="@style/EmptyStateButton"/> + </LinearLayout> +</LinearLayout> diff --git a/src/com/android/documentsui/AbstractActionHandler.java b/src/com/android/documentsui/AbstractActionHandler.java index c450c70de..53c507ef3 100644 --- a/src/com/android/documentsui/AbstractActionHandler.java +++ b/src/com/android/documentsui/AbstractActionHandler.java @@ -177,6 +177,11 @@ public abstract class AbstractActionHandler<T extends FragmentActivity & CommonA } @Override + public void requestQuietModeDisabled(RootInfo info, UserId userId) { + new RequestQuietModeDisabledTask(mActivity, userId).execute(); + } + + @Override public void onActivityResult(int requestCode, int resultCode, Intent data) { switch (requestCode) { case CODE_AUTHENTICATION: diff --git a/src/com/android/documentsui/ActionHandler.java b/src/com/android/documentsui/ActionHandler.java index 71cccf9ee..15124eb33 100644 --- a/src/com/android/documentsui/ActionHandler.java +++ b/src/com/android/documentsui/ActionHandler.java @@ -89,6 +89,8 @@ public interface ActionHandler { */ void startAuthentication(PendingIntent intent); + void requestQuietModeDisabled(RootInfo info, UserId userId); + void showAppDetails(ResolveInfo info, UserId userId); void openRoot(RootInfo root); diff --git a/src/com/android/documentsui/RequestQuietModeDisabledTask.java b/src/com/android/documentsui/RequestQuietModeDisabledTask.java new file mode 100644 index 000000000..238e4f96c --- /dev/null +++ b/src/com/android/documentsui/RequestQuietModeDisabledTask.java @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.documentsui; + +import static androidx.core.util.Preconditions.checkNotNull; + +import android.content.Context; +import android.os.AsyncTask; + +import com.android.documentsui.base.UserId; + +import java.lang.ref.WeakReference; + +/** + * A task to request disabling quiet mode for a given user. + */ +class RequestQuietModeDisabledTask extends AsyncTask<Void, Void, Void> { + + private final WeakReference<Context> mContextWeakReference; + private final UserId mUserId; + + RequestQuietModeDisabledTask(Context context, UserId userId) { + mContextWeakReference = new WeakReference<>(checkNotNull(context)); + mUserId = checkNotNull(userId); + } + + @Override + protected Void doInBackground(Void... voids) { + Context context = mContextWeakReference.get(); + if (context != null) { + mUserId.requestQuietModeDisabled(context); + } + return null; + } +} diff --git a/src/com/android/documentsui/dirlist/InflateMessageDocumentHolder.java b/src/com/android/documentsui/dirlist/InflateMessageDocumentHolder.java index 9148345e6..4b1113675 100644 --- a/src/com/android/documentsui/dirlist/InflateMessageDocumentHolder.java +++ b/src/com/android/documentsui/dirlist/InflateMessageDocumentHolder.java @@ -22,6 +22,7 @@ import android.text.TextUtils; import android.view.View; import android.view.ViewGroup; import android.widget.ImageView; +import android.widget.ProgressBar; import android.widget.TextView; import com.android.documentsui.R; @@ -47,11 +48,15 @@ final class InflateMessageDocumentHolder extends MessageHolder { private View mContentView; private View mCrossProfileView; + private View mCrossProfileContent; + private ProgressBar mCrossProfileProgress; public InflateMessageDocumentHolder(Context context, ViewGroup parent) { super(context, parent, R.layout.item_doc_inflated_message); mContentView = itemView.findViewById(R.id.content); mCrossProfileView = itemView.findViewById(R.id.cross_profile); + mCrossProfileContent = mCrossProfileView.findViewById(R.id.cross_profile_content); + mCrossProfileProgress = mCrossProfileView.findViewById(R.id.cross_profile_progress); mContentMessage = mContentView.findViewById(R.id.message); mContentImage = mContentView.findViewById(R.id.artwork); @@ -76,7 +81,9 @@ final class InflateMessageDocumentHolder extends MessageHolder { } } - private void onButtonClick(View button) { + private void onCrossProfileButtonClick(View button) { + mCrossProfileContent.setVisibility(View.GONE); + mCrossProfileProgress.setVisibility(View.VISIBLE); mMessage.runCallback(); } @@ -91,6 +98,9 @@ final class InflateMessageDocumentHolder extends MessageHolder { private void bindCrossProfileMessageView() { mContentView.setVisibility(View.GONE); mCrossProfileView.setVisibility(View.VISIBLE); + mCrossProfileContent.setVisibility(View.VISIBLE); + mCrossProfileProgress.setVisibility(View.GONE); + mCrossProfileTitle.setText(mMessage.getTitleString()); if (!TextUtils.isEmpty(mMessage.getMessageString())) { mCrossProfileMessage.setVisibility(View.VISIBLE); @@ -102,7 +112,7 @@ final class InflateMessageDocumentHolder extends MessageHolder { if (!TextUtils.isEmpty(mMessage.getButtonString())) { mCrossProfileButton.setVisibility(View.VISIBLE); mCrossProfileButton.setText(mMessage.getButtonString()); - mCrossProfileButton.setOnClickListener(this::onButtonClick); + mCrossProfileButton.setOnClickListener(this::onCrossProfileButtonClick); } else { mCrossProfileButton.setVisibility(View.GONE); } diff --git a/src/com/android/documentsui/dirlist/Message.java b/src/com/android/documentsui/dirlist/Message.java index 4fc7c497f..b5074e4a1 100644 --- a/src/com/android/documentsui/dirlist/Message.java +++ b/src/com/android/documentsui/dirlist/Message.java @@ -21,7 +21,6 @@ import android.app.AuthenticationRequiredException; import android.content.pm.PackageManager; import android.content.res.Resources; import android.graphics.drawable.Drawable; -import android.os.AsyncTask; import androidx.annotation.Nullable; @@ -215,14 +214,8 @@ abstract class Message { CharSequence buttonText = null; if (mCanModifyQuietMode) { buttonText = mEnv.getContext().getResources().getText(R.string.quiet_mode_button); - mCallback = () -> - new AsyncTask<Void, Void, Void>() { - @Override - protected Void doInBackground(Void... voids) { - userId.requestQuietModeDisabled(mEnv.getContext()); - return null; - } - }.execute(); + mCallback = () -> mEnv.getActionHandler().requestQuietModeDisabled( + mEnv.getDisplayState().stack.getRoot(), userId); } update( mEnv.getContext().getResources().getText(R.string.quiet_mode_error_title), diff --git a/tests/common/com/android/documentsui/testing/TestActionHandler.java b/tests/common/com/android/documentsui/testing/TestActionHandler.java index f28234203..de7b266d0 100644 --- a/tests/common/com/android/documentsui/testing/TestActionHandler.java +++ b/tests/common/com/android/documentsui/testing/TestActionHandler.java @@ -24,6 +24,7 @@ import com.android.documentsui.AbstractActionHandler; import com.android.documentsui.TestActivity; import com.android.documentsui.base.DocumentInfo; import com.android.documentsui.base.RootInfo; +import com.android.documentsui.base.UserId; import java.util.function.Consumer; @@ -33,6 +34,7 @@ public class TestActionHandler extends AbstractActionHandler<TestActivity> { public final TestEventHandler<ItemDetails<String>> open = new TestEventHandler<>(); public boolean mDeleteHappened; + public boolean mRequestDisablingQuietModeHappened; public DocumentInfo nextRootDocument; @@ -64,6 +66,11 @@ public class TestActionHandler extends AbstractActionHandler<TestActivity> { } @Override + public void requestQuietModeDisabled(RootInfo info, UserId userId) { + mRequestDisablingQuietModeHappened = true; + } + + @Override public void openRoot(RootInfo root) { throw new UnsupportedOperationException(); } diff --git a/tests/unit/com/android/documentsui/dirlist/InflateMessageDocumentHolderTest.java b/tests/unit/com/android/documentsui/dirlist/InflateMessageDocumentHolderTest.java new file mode 100644 index 000000000..436e4fbca --- /dev/null +++ b/tests/unit/com/android/documentsui/dirlist/InflateMessageDocumentHolderTest.java @@ -0,0 +1,91 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.documentsui.dirlist; + +import static com.google.common.truth.Truth.assertThat; + +import android.content.Context; +import android.view.View; +import android.widget.Button; + +import androidx.test.filters.SmallTest; +import androidx.test.platform.app.InstrumentationRegistry; + +import com.android.documentsui.CrossProfileQuietModeException; +import com.android.documentsui.Model; +import com.android.documentsui.R; +import com.android.documentsui.base.State; +import com.android.documentsui.testing.TestActionHandler; +import com.android.documentsui.testing.TestEnv; +import com.android.documentsui.testing.TestProvidersAccess; + +import org.junit.Before; +import org.junit.Test; + +@SmallTest +public final class InflateMessageDocumentHolderTest { + + private Context mContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); + private Runnable mDefaultCallback = () -> { + }; + private Message mInflateMessage; + private TestActionHandler mTestActionHandler = new TestActionHandler(); + private InflateMessageDocumentHolder mHolder; + + @Before + public void setUp() { + DocumentsAdapter.Environment env = + new TestEnvironment(mContext, TestEnv.create(), mTestActionHandler); + env.getDisplayState().action = State.ACTION_GET_CONTENT; + env.getDisplayState().canShareAcrossProfile = true; + env.getDisplayState().supportsCrossProfile = true; + mInflateMessage = new Message.InflateMessage(env, mDefaultCallback); + mContext.setTheme(R.style.DocumentsTheme); + mContext.getTheme().applyStyle(R.style.DocumentsDefaultTheme, /* force= */false); + + mHolder = new InflateMessageDocumentHolder(mContext, /* parent= */null); + } + + @Test + public void testClickingButtonShouldShowProgressBar() { + Model.Update error = new Model.Update( + new CrossProfileQuietModeException(TestProvidersAccess.OtherUser.USER_ID), + /* remoteActionsEnabled= */ true); + mInflateMessage.update(error); + + mHolder.bind(mInflateMessage); + + View content = mHolder.itemView.findViewById(R.id.content); + View crossProfile = mHolder.itemView.findViewById(R.id.cross_profile); + View crossProfileContent = mHolder.itemView.findViewById(R.id.cross_profile_content); + View progress = mHolder.itemView.findViewById(R.id.cross_profile_progress); + Button button = mHolder.itemView.findViewById(R.id.button); + + assertThat(content.getVisibility()).isEqualTo(View.GONE); + assertThat(crossProfile.getVisibility()).isEqualTo(View.VISIBLE); + assertThat(crossProfileContent.getVisibility()).isEqualTo(View.VISIBLE); + assertThat(progress.getVisibility()).isEqualTo(View.GONE); + + if (button.getVisibility() == View.VISIBLE) { + // The button is visible when docsUI has the permission to modify quiet mode. + assertThat(button.callOnClick()).isTrue(); + assertThat(crossProfile.getVisibility()).isEqualTo(View.VISIBLE); + assertThat(crossProfileContent.getVisibility()).isEqualTo(View.GONE); + assertThat(progress.getVisibility()).isEqualTo(View.VISIBLE); + } + } +} diff --git a/tests/unit/com/android/documentsui/dirlist/MessageTest.java b/tests/unit/com/android/documentsui/dirlist/MessageTest.java index 3eff20e7f..54dbbc501 100644 --- a/tests/unit/com/android/documentsui/dirlist/MessageTest.java +++ b/tests/unit/com/android/documentsui/dirlist/MessageTest.java @@ -19,12 +19,9 @@ package com.android.documentsui.dirlist; import static com.google.common.truth.Truth.assertThat; import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.timeout; -import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import android.content.Context; -import android.os.UserHandle; import android.os.UserManager; import androidx.core.util.Preconditions; @@ -53,16 +50,18 @@ public final class MessageTest { private Runnable mDefaultCallback = () -> { }; private UserManager mUserManager; + private TestActionHandler mTestActionHandler; @Before public void setUp() { mContext = mock(Context.class); mUserManager = UserManagers.create(); + mTestActionHandler = new TestActionHandler(); when(mContext.getSystemService(Context.USER_SERVICE)).thenReturn(mUserManager); when(mContext.getResources()).thenReturn( InstrumentationRegistry.getInstrumentation().getTargetContext().getResources()); DocumentsAdapter.Environment env = - new TestEnvironment(mContext, TestEnv.create(), new TestActionHandler()); + new TestEnvironment(mContext, TestEnv.create(), mTestActionHandler); env.getDisplayState().action = State.ACTION_GET_CONTENT; mInflateMessage = new Message.InflateMessage(env, mDefaultCallback); } @@ -100,7 +99,7 @@ public final class MessageTest { mContext.getString(R.string.quiet_mode_button)); assertThat(mInflateMessage.mCallback).isNotNull(); mInflateMessage.mCallback.run(); - verify(mUserManager, timeout(3000)) - .requestQuietModeEnabled(false, UserHandle.of(mUserId.getIdentifier())); + + assertThat(mTestActionHandler.mRequestDisablingQuietModeHappened).isTrue(); } } |