diff options
22 files changed, 290 insertions, 380 deletions
diff --git a/AndroidManifest.xml b/AndroidManifest.xml index 89ccd9732..ba0556628 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -91,14 +91,6 @@ android:theme="@style/DocumentsTheme"> </activity> - <activity - android:name=".ForResultForwarderActivity" - android:theme="@android:style/Theme.NoDisplay" - android:excludeFromRecents="true" - android:finishOnCloseSystemDialogs="true" - android:exported="false"> - </activity> - <!-- Preserve original launcher activity from Nougat. --> <activity-alias android:name=".LauncherActivity" diff --git a/res/color/doc_list_item_subtitle_color.xml b/res/color/doc_list_item_subtitle_color.xml new file mode 100644 index 000000000..5f5896e7a --- /dev/null +++ b/res/color/doc_list_item_subtitle_color.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + ~ 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. + --> + +<selector xmlns:android="http://schemas.android.com/apk/res/android"> + <item android:state_enabled="false" + android:color="@color/doc_list_item_subtitle_disabled" /> + <item android:color="@color/doc_list_item_subtitle_enabled" /> +</selector> 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/res/layout/item_doc_list.xml b/res/layout/item_doc_list.xml index 706d9c226..1189482a2 100644 --- a/res/layout/item_doc_list.xml +++ b/res/layout/item_doc_list.xml @@ -117,7 +117,7 @@ android:ellipsize="end" android:singleLine="true" android:textAlignment="viewStart" - android:textAppearance="@android:style/TextAppearance.Material.Caption"/> + android:textAppearance="@style/ItemDocListCaptionText"/> <TextView android:id="@+id/size" @@ -128,7 +128,7 @@ android:ellipsize="end" android:singleLine="true" android:textAlignment="viewStart" - android:textAppearance="@android:style/TextAppearance.Material.Caption"/> + android:textAppearance="@style/ItemDocListCaptionText"/> <TextView android:id="@+id/file_type" @@ -139,7 +139,7 @@ android:ellipsize="end" android:singleLine="true" android:textAlignment="viewStart" - android:textAppearance="@android:style/TextAppearance.Material.Caption"/> + android:textAppearance="@style/ItemDocListCaptionText"/> </LinearLayout> </LinearLayout> diff --git a/res/values-night/colors.xml b/res/values-night/colors.xml index 1a6c174ff..86bcbbc48 100644 --- a/res/values-night/colors.xml +++ b/res/values-night/colors.xml @@ -29,4 +29,8 @@ <color name="edge_effect">@android:color/white</color> <color name="tab_indicator_color">#669DF6</color> <!-- Blue 400 --> + + <!-- AppCompat.textColorSecondary --> + <color name="doc_list_item_subtitle_enabled">#b3ffffff</color> + <color name="doc_list_item_subtitle_disabled">#36ffffff</color> </resources> diff --git a/res/values/colors.xml b/res/values/colors.xml index 901666430..e00984ada 100644 --- a/res/values/colors.xml +++ b/res/values/colors.xml @@ -49,4 +49,7 @@ <color name="tab_indicator_color">#1A73E8</color> <!-- Blue 600 --> <color name="edge_effect">@android:color/black</color> + + <color name="doc_list_item_subtitle_enabled">#5F6368</color> <!-- Gray 700 --> + <color name="doc_list_item_subtitle_disabled">#613c4043</color> <!-- 38% Grey800 --> </resources> diff --git a/res/values/styles_text.xml b/res/values/styles_text.xml index 3ea510c4b..f90305e0e 100644 --- a/res/values/styles_text.xml +++ b/res/values/styles_text.xml @@ -119,4 +119,8 @@ <item name="fontFamily">@string/config_fontFamilyMedium</item> </style> + <style name="ItemDocListCaptionText" parent="@android:style/TextAppearance.Material.Caption"> + <item name="android:textColor">@color/doc_list_item_subtitle_color</item> + </style> + </resources>
\ No newline at end of file diff --git a/src/com/android/documentsui/AbstractActionHandler.java b/src/com/android/documentsui/AbstractActionHandler.java index c450c70de..0c612eddd 100644 --- a/src/com/android/documentsui/AbstractActionHandler.java +++ b/src/com/android/documentsui/AbstractActionHandler.java @@ -87,9 +87,7 @@ public abstract class AbstractActionHandler<T extends FragmentActivity & CommonA implements ActionHandler { @VisibleForTesting - public static final int CODE_FORWARD = 42; public static final int CODE_AUTHENTICATION = 43; - public static final int CODE_FORWARD_CROSS_PROFILE = 44; @VisibleForTesting static final int LOADER_ID = 42; @@ -177,6 +175,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/BaseActivity.java b/src/com/android/documentsui/BaseActivity.java index d0ffe593c..0ddf001be 100644 --- a/src/com/android/documentsui/BaseActivity.java +++ b/src/com/android/documentsui/BaseActivity.java @@ -619,10 +619,10 @@ public abstract class BaseActivity // Causes talkback to announce the activity's new title String appName = getString(R.string.files_label); - if (getTitle().toString().isEmpty()) { + if (getTitle() == null || getTitle().toString().isEmpty()) { // First launch, TalkBack announces app name. setTitle(String.format("%s. %s", appName, mState.stack.getTitle())); - } else { + } else if (mState.stack.getTitle() != null) { setTitle(mState.stack.getTitle()); } diff --git a/src/com/android/documentsui/ForResultForwarderActivity.java b/src/com/android/documentsui/ForResultForwarderActivity.java deleted file mode 100644 index 61cee71dc..000000000 --- a/src/com/android/documentsui/ForResultForwarderActivity.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * 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 android.app.Activity; -import android.content.Context; -import android.content.Intent; -import android.os.Bundle; -import android.util.Log; - -import com.android.documentsui.base.UserId; - -/** - * Forwards a cross-profile startActivityForResult intent. - */ -public class ForResultForwarderActivity extends Activity { - - private static final String TAG = "ForResultForwarderActiv"; - private static final String EXTRA_INTENT = "EXTRA_INTENT"; - private static final String EXTRA_USER = "EXTRA_USER"; - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - final Intent intent = getIntent(); - - if (!intent.hasExtra(EXTRA_INTENT) || !intent.hasExtra(EXTRA_USER)) { - Log.e(TAG, "Missing intent or user"); - setResult(Activity.RESULT_CANCELED); - finish(); - return; - } - - Intent targetIntent = intent.getParcelableExtra(EXTRA_INTENT); - // We should never have the default value because of the above check - UserId targetUserId = UserId.of(intent.getIntExtra(EXTRA_USER, /* defaultValue= */ -1)); - - targetIntent.addFlags( - Intent.FLAG_ACTIVITY_FORWARD_RESULT | Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP); - try { - targetUserId.startActivityAsUser(this, targetIntent); - } catch (RuntimeException e) { - Log.e(TAG, "Failed to forward activity"); - setResult(Activity.RESULT_CANCELED); - } - finish(); - } - - public static Intent getIntent(Context context, Intent intent, UserId targetUserId) { - Intent forwarder = new Intent(context, ForResultForwarderActivity.class); - forwarder.putExtra(EXTRA_INTENT, intent); - forwarder.putExtra(EXTRA_USER, targetUserId.getIdentifier()); - return forwarder; - } -} 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/src/com/android/documentsui/picker/ActionHandler.java b/src/com/android/documentsui/picker/ActionHandler.java index c58927dc7..18a1487ca 100644 --- a/src/com/android/documentsui/picker/ActionHandler.java +++ b/src/com/android/documentsui/picker/ActionHandler.java @@ -43,7 +43,6 @@ import androidx.recyclerview.selection.ItemDetailsLookup.ItemDetails; import com.android.documentsui.AbstractActionHandler; import com.android.documentsui.ActivityConfig; import com.android.documentsui.DocumentsAccess; -import com.android.documentsui.ForResultForwarderActivity; import com.android.documentsui.Injector; import com.android.documentsui.MetricConsts; import com.android.documentsui.Metrics; @@ -243,46 +242,6 @@ class ActionHandler<T extends FragmentActivity & Addons> extends AbstractActionH } @Override - public void onActivityResult(int requestCode, int resultCode, Intent data) { - if (DEBUG) { - Log.d(TAG, "onActivityResult() code=" + resultCode); - } - - // Only relay back results when not canceled; otherwise stick around to - // let the user pick another app/backend. - switch (requestCode) { - case CODE_FORWARD: - case CODE_FORWARD_CROSS_PROFILE: - onExternalAppResult(requestCode, resultCode, data); - break; - default: - super.onActivityResult(requestCode, resultCode, data); - } - } - - private void onExternalAppResult(int requestCode, int resultCode, Intent data) { - if (resultCode != FragmentActivity.RESULT_CANCELED) { - if (requestCode == CODE_FORWARD_CROSS_PROFILE) { - UserId otherUser = UserId.CURRENT_USER.equals(mUserIdManager.getSystemUser()) - ? mUserIdManager.getManagedUser() - : mUserIdManager.getSystemUser(); - if (!mState.canInteractWith(otherUser)) { - mDialogs.showActionNotAllowed(); - return; - } - } - // Remember that we last picked via external app - mLastAccessed.setLastAccessedToExternalApp(mActivity); - - updatePickResult(data, false, MetricConsts.ROOT_THIRD_PARTY_APP); - - // Pass back result to original caller - mActivity.setResult(resultCode, data, 0); - mActivity.finish(); - } - } - - @Override public void openInNewWindow(DocumentStack path) { // Open new window support only depends on vanilla Activity, so it is // implemented in our parent class. But we don't support that in @@ -311,27 +270,30 @@ class ActionHandler<T extends FragmentActivity & Addons> extends AbstractActionH } Intent intent = new Intent(mActivity.getIntent()); - final int flagsRemoved = Intent.FLAG_ACTIVITY_FORWARD_RESULT - | Intent.FLAG_GRANT_READ_URI_PERMISSION + final int flagsRemoved = Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION; intent.setFlags(intent.getFlags() & ~flagsRemoved); + intent.addFlags(Intent.FLAG_ACTIVITY_FORWARD_RESULT); + intent.addFlags(Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP); intent.setComponent(new ComponentName( info.activityInfo.applicationInfo.packageName, info.activityInfo.name)); - if (!UserId.CURRENT_USER.equals(userId)) { - intent = ForResultForwarderActivity.getIntent(mActivity, intent, userId); - } try { boolean isCurrentUser = UserId.CURRENT_USER.equals(userId); - mActivity.startActivityForResult(intent, - isCurrentUser ? CODE_FORWARD : CODE_FORWARD_CROSS_PROFILE); + if (isCurrentUser) { + mActivity.startActivity(intent); + } else { + userId.startActivityAsUser(mActivity, intent); + } + mActivity.finish(); } catch (SecurityException | ActivityNotFoundException e) { Log.e(TAG, "Caught error: " + e.getLocalizedMessage()); mInjector.dialogs.showNoApplicationFound(); } } + @Override public void springOpenDirectory(DocumentInfo doc) { } diff --git a/tests/AndroidManifest.xml b/tests/AndroidManifest.xml index 1fd1b7908..cb43811d4 100644 --- a/tests/AndroidManifest.xml +++ b/tests/AndroidManifest.xml @@ -37,13 +37,6 @@ </intent-filter> </activity> - <activity android:name="com.android.documentsui.PickActivityTest$ReturnResultActivity"> - <intent-filter> - <action android:name="com.android.documentsui.test.action.RETURN_RESULT" /> - <category android:name="android.intent.category.DEFAULT" /> - </intent-filter> - </activity> - <provider android:name="com.android.documentsui.StubProvider" 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/ForResultForwarderActivityTest.java b/tests/unit/com/android/documentsui/ForResultForwarderActivityTest.java deleted file mode 100644 index 56e549afa..000000000 --- a/tests/unit/com/android/documentsui/ForResultForwarderActivityTest.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * 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 com.google.common.truth.Truth.assertThat; - -import android.content.ComponentName; -import android.content.Context; -import android.content.Intent; -import android.content.pm.ResolveInfo; - -import androidx.test.filters.SmallTest; -import androidx.test.platform.app.InstrumentationRegistry; - -import com.android.documentsui.testing.TestProvidersAccess; - -import org.junit.Before; -import org.junit.Test; - -@SmallTest -public class ForResultForwarderActivityTest { - - private Context mTargetContext; - - @Before - public void setUp() throws Exception { - mTargetContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); - } - - @Test - public void testActivityNotExported() { - Intent originalIntent = new Intent("some_action"); - Intent intent = ForResultForwarderActivity.getIntent(mTargetContext, originalIntent, - TestProvidersAccess.USER_ID); - - ResolveInfo info = mTargetContext.getPackageManager().resolveActivity(intent, 0); - assertThat(info.activityInfo.getComponentName()) - .isEqualTo(new ComponentName(mTargetContext, ForResultForwarderActivity.class)); - assertThat(info.activityInfo.exported).isFalse(); - } -} diff --git a/tests/unit/com/android/documentsui/PickActivityTest.java b/tests/unit/com/android/documentsui/PickActivityTest.java index 9311822f7..1fbc20d9b 100644 --- a/tests/unit/com/android/documentsui/PickActivityTest.java +++ b/tests/unit/com/android/documentsui/PickActivityTest.java @@ -25,7 +25,6 @@ import android.app.Instrumentation; import android.content.Context; import android.content.Intent; import android.net.Uri; -import android.os.Bundle; import android.os.SystemClock; import android.provider.DocumentsContract; @@ -123,43 +122,4 @@ public class PickActivityTest { assertThat(pickActivity.isFinishing()).isFalse(); testDialogs.assertActionNotAllowedShown(); } - - @Test - public void testStartForResultForwarderActivity() { - Intent originalIntent = new Intent("com.android.documentsui.test.action.RETURN_RESULT"); - Intent intent = ForResultForwarderActivity.getIntent(mTargetContext, originalIntent, - TestProvidersAccess.USER_ID); - - PickActivity pickActivity = mRule.launchActivity(intentGetContent); - pickActivity.startActivityForResult(intent, AbstractActionHandler.CODE_FORWARD); - SystemClock.sleep(3000); - - Instrumentation.ActivityResult result = mRule.getActivityResult(); - assertThat(result.getResultCode()).isEqualTo(Activity.RESULT_OK); - assertThat(result.getResultData().getStringExtra(RESULT_EXTRA)).isEqualTo(RESULT_DATA); - } - - @Test - public void testStartForResultForwarderActivity_noActivity() { - Intent originalIntent = new Intent("no_app_handles_this_intent_action"); - Intent intent = ForResultForwarderActivity.getIntent(mTargetContext, originalIntent, - TestProvidersAccess.USER_ID); - - PickActivity pickActivity = mRule.launchActivity(intentGetContent); - pickActivity.startActivityForResult(intent, AbstractActionHandler.CODE_FORWARD); - SystemClock.sleep(3000); - - assertThat(pickActivity.isFinishing()).isFalse(); - } - - public static class ReturnResultActivity extends Activity { - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - Intent data = new Intent(); - data.putExtra(RESULT_EXTRA, RESULT_DATA); - setResult(Activity.RESULT_OK, data); - finish(); - } - } } 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(); } } diff --git a/tests/unit/com/android/documentsui/picker/ActionHandlerTest.java b/tests/unit/com/android/documentsui/picker/ActionHandlerTest.java index db0922994..3601bf541 100644 --- a/tests/unit/com/android/documentsui/picker/ActionHandlerTest.java +++ b/tests/unit/com/android/documentsui/picker/ActionHandlerTest.java @@ -27,6 +27,7 @@ import android.app.Activity; import android.content.ClipData; import android.content.ComponentName; import android.content.Intent; +import android.content.pm.ResolveInfo; import android.net.Uri; import android.os.AsyncTask; import android.provider.DocumentsContract; @@ -36,9 +37,7 @@ import androidx.fragment.app.FragmentActivity; import androidx.test.filters.MediumTest; import androidx.test.runner.AndroidJUnit4; -import com.android.documentsui.AbstractActionHandler; import com.android.documentsui.DocumentsAccess; -import com.android.documentsui.ForResultForwarderActivity; import com.android.documentsui.Injector; import com.android.documentsui.R; import com.android.documentsui.TestUserIdManager; @@ -523,113 +522,57 @@ public class ActionHandlerTest { mActivity.finishedHandler.assertCalled(); } - @Test - public void testOnAppPickedResult_OnOK() throws Exception { - Intent intent = new Intent(); - mHandler.onActivityResult(AbstractActionHandler.CODE_FORWARD, Activity.RESULT_OK, intent); - mActivity.finishedHandler.assertCalled(); - mActivity.setResult.assertCalled(); - - assertEquals(Activity.RESULT_OK, (long) mActivity.setResult.getLastValue().first); - assertEquals(intent, mActivity.setResult.getLastValue().second); - } - - @Test - public void testOnAppPickedResult_OnOK_crossProfile() throws Exception { - mEnv.state.canShareAcrossProfile = true; - mTestUserIdManager.managedUser = TestProvidersAccess.OtherUser.USER_ID; - mTestUserIdManager.systemUser = TestProvidersAccess.USER_ID; - - Intent intent = new Intent(); - mHandler.onActivityResult(AbstractActionHandler.CODE_FORWARD_CROSS_PROFILE, - Activity.RESULT_OK, intent); - mActivity.finishedHandler.assertCalled(); - mActivity.setResult.assertCalled(); - - assertEquals(Activity.RESULT_OK, (long) mActivity.setResult.getLastValue().first); - assertEquals(intent, mActivity.setResult.getLastValue().second); - mEnv.dialogs.assertActionNotAllowedNotShown(); - } - - @Test - public void testOnAppPickedResult_OnOK_crossProfile_withoutPermission() throws Exception { - mEnv.state.canShareAcrossProfile = false; - mTestUserIdManager.managedUser = TestProvidersAccess.OtherUser.USER_ID; - mTestUserIdManager.systemUser = TestProvidersAccess.USER_ID; - - Intent intent = new Intent(); - mHandler.onActivityResult(AbstractActionHandler.CODE_FORWARD_CROSS_PROFILE, - Activity.RESULT_OK, intent); - mActivity.finishedHandler.assertNotCalled(); - mActivity.setResult.assertNotCalled(); - mEnv.dialogs.assertActionNotAllowedShown(); - } - - @Test - public void testOnAppPickedResult_OnNotOK() throws Exception { - Intent intent = new Intent(); - mHandler.onActivityResult(0, Activity.RESULT_OK, intent); - mActivity.finishedHandler.assertNotCalled(); - mActivity.setResult.assertNotCalled(); - - mHandler.onActivityResult(AbstractActionHandler.CODE_FORWARD, Activity.RESULT_CANCELED, - intent); - mActivity.finishedHandler.assertNotCalled(); - mActivity.setResult.assertNotCalled(); - } - - @Test - public void testOnAppPickedResult_OnNotOK_crossProfile() throws Exception { - Intent intent = new Intent(); - mHandler.onActivityResult(AbstractActionHandler.CODE_FORWARD_CROSS_PROFILE, - Activity.RESULT_CANCELED, - intent); - mActivity.finishedHandler.assertNotCalled(); - mActivity.setResult.assertNotCalled(); - } @Test public void testOpenAppRoot() throws Exception { mHandler.openRoot(TestResolveInfo.create(), TestProvidersAccess.USER_ID); - assertEquals((long) mActivity.startActivityForResult.getLastValue().second, - AbstractActionHandler.CODE_FORWARD); - assertNotNull(mActivity.startActivityForResult.getLastValue().first); + assertNotNull(mActivity.startActivity.getLastValue()); } @Test public void testOpenAppRoot_otherUser() throws Exception { + ResolveInfo info = TestResolveInfo.create(); mEnv.state.canShareAcrossProfile = true; - mHandler.openRoot(TestResolveInfo.create(), TestProvidersAccess.OtherUser.USER_ID); - assertEquals((long) mActivity.startActivityForResult.getLastValue().second, - AbstractActionHandler.CODE_FORWARD_CROSS_PROFILE); - Intent forwarderIntent = mActivity.startActivityForResult.getLastValue().first; - assertThat(forwarderIntent.getComponent()).isEqualTo( - new ComponentName(mActivity.getPackageName(), - ForResultForwarderActivity.class.getName())); - Intent originalIntent = forwarderIntent.getParcelableExtra(EXTRA_INTENT); - assertThat(originalIntent).isNotNull(); - assertThat(forwarderIntent.getIntExtra(EXTRA_USER, -1)) - .isEqualTo(TestProvidersAccess.OtherUser.USER_ID.getIdentifier()); + mHandler.openRoot(info, TestProvidersAccess.OtherUser.USER_ID); + assertThat(mActivity.startActivityAsUser.getLastValue().first.getComponent()).isEqualTo( + new ComponentName(info.activityInfo.applicationInfo.packageName, + info.activityInfo.name)); + assertThat(mActivity.startActivityAsUser.getLastValue().second) + .isEqualTo(TestProvidersAccess.OtherUser.USER_HANDLE); + + int flags = mActivity.startActivityAsUser.getLastValue().first.getFlags(); + assertEquals(0, flags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION); + assertEquals(0, flags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION); + assertEquals(0, flags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION); + assertEquals(0, flags & Intent.FLAG_GRANT_READ_URI_PERMISSION); + assertEquals(Intent.FLAG_ACTIVITY_FORWARD_RESULT, + flags & Intent.FLAG_ACTIVITY_FORWARD_RESULT); + assertEquals(Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP, + flags & Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP); } @Test - public void testOpenAppRoot_removeFlags() throws Exception { + public void testOpenAppRoot_removeFlagsAddForwardResult() throws Exception { + ResolveInfo info = TestResolveInfo.create(); mActivity.intent.setFlags(Intent.FLAG_ACTIVITY_FORWARD_RESULT | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION); - mHandler.openRoot(TestResolveInfo.create(), TestProvidersAccess.USER_ID); - assertEquals((long) mActivity.startActivityForResult.getLastValue().second, - AbstractActionHandler.CODE_FORWARD); - assertNotNull(mActivity.startActivityForResult.getLastValue().first); + mHandler.openRoot(info, TestProvidersAccess.USER_ID); + assertThat(mActivity.startActivity.getLastValue().getComponent()).isEqualTo( + new ComponentName(info.activityInfo.applicationInfo.packageName, + info.activityInfo.name)); - int flags = mActivity.startActivityForResult.getLastValue().first.getFlags(); - assertEquals(0, flags & Intent.FLAG_ACTIVITY_FORWARD_RESULT); + int flags = mActivity.startActivity.getLastValue().getFlags(); assertEquals(0, flags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION); assertEquals(0, flags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION); assertEquals(0, flags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION); assertEquals(0, flags & Intent.FLAG_GRANT_READ_URI_PERMISSION); + assertEquals(Intent.FLAG_ACTIVITY_FORWARD_RESULT, + flags & Intent.FLAG_ACTIVITY_FORWARD_RESULT); + assertEquals(Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP, + flags & Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP); } @Test @@ -638,8 +581,8 @@ public class ActionHandlerTest { mActivity.intent.putExtra(Intent.EXTRA_CONTENT_QUERY, queryContent); mHandler.openRoot(TestResolveInfo.create(), TestProvidersAccess.USER_ID); assertEquals(queryContent, - mActivity.startActivityForResult.getLastValue().first.getStringExtra( - Intent.EXTRA_CONTENT_QUERY)); + mActivity.startActivity.getLastValue().getStringExtra( + Intent.EXTRA_CONTENT_QUERY)); } @Test @@ -652,26 +595,6 @@ public class ActionHandlerTest { } @Test - public void testOpenAppRoot_happensWithPermission_differentUser() throws Exception { - final String queryContent = "query"; - mEnv.state.canShareAcrossProfile = true; - mActivity.intent.putExtra(Intent.EXTRA_CONTENT_QUERY, queryContent); - mHandler.openRoot(TestResolveInfo.create(), TestProvidersAccess.OtherUser.USER_ID); - - Intent forwarderIntent = mActivity.startActivityForResult.getLastValue().first; - assertThat(forwarderIntent.getComponent()).isEqualTo( - new ComponentName(mActivity.getPackageName(), - ForResultForwarderActivity.class.getName())); - - Intent originalIntent = forwarderIntent.getParcelableExtra(EXTRA_INTENT); - assertThat(originalIntent.getStringExtra( - Intent.EXTRA_CONTENT_QUERY)).isEqualTo(queryContent); - assertThat(forwarderIntent.getIntExtra(EXTRA_USER, -1)) - .isEqualTo(TestProvidersAccess.OtherUser.USER_ID.getIdentifier()); - mEnv.dialogs.assertActionNotAllowedNotShown(); - } - - @Test public void testPreviewItem() throws Exception { mActivity.resources.setQuickViewerPackage("corptropolis.viewer"); mActivity.currentRoot = TestProvidersAccess.HOME; |