Merge "Fix broken a11y function"
diff --git a/res/layout-sw720dp/item_doc_header_message.xml b/res/layout-sw720dp/item_doc_header_message.xml
index efec111..9b797ad 100644
--- a/res/layout-sw720dp/item_doc_header_message.xml
+++ b/res/layout-sw720dp/item_doc_header_message.xml
@@ -13,37 +13,52 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:animateLayoutChanges="true"
- android:id="@+id/message_container"
- android:layout_height="wrap_content"
+<com.google.android.material.card.MaterialCardView
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
- android:layout_marginTop="@dimen/list_item_padding"
- android:layout_marginBottom="0dp"
- android:minHeight="?android:attr/listPreferredItemHeightSmall">
+ android:layout_height="wrap_content"
+ android:layout_margin="4dp"
+ android:elevation="0dp"
+ android:duplicateParentState="true"
+ app:cardElevation="0dp"
+ app:strokeWidth="1dp"
+ app:strokeColor="?android:strokeColor">
- <ImageView
- android:contentDescription="@null"
- android:id="@+id/message_icon"
- android:layout_height="@dimen/icon_size"
- android:layout_width="@dimen/icon_size"
- android:layout_marginStart="@dimen/list_item_padding"
- android:layout_marginEnd="12dp"
- android:scaleType="centerInside"/>
-
- <TextView
- android:id="@+id/message_textview"
+ <RelativeLayout
+ android:animateLayoutChanges="true"
+ android:id="@+id/message_container"
android:layout_height="wrap_content"
- android:layout_width="wrap_content"
- android:layout_toEndOf="@+id/message_icon"
- android:selectAllOnFocus="true"/>
+ android:layout_width="match_parent"
+ android:minHeight="?android:attr/listPreferredItemHeightSmall">
- <Button
- android:id="@+id/button_dismiss"
- android:layout_height="wrap_content"
- android:layout_width="wrap_content"
- android:layout_alignEnd="@+id/message_textview"
- android:layout_below="@+id/message_textview"
- android:text="@android:string/ok"
- style="?attr/materialButtonStyle"/>
-</RelativeLayout>
+ <ImageView
+ android:contentDescription="@null"
+ android:id="@+id/message_icon"
+ android:layout_height="@dimen/icon_size"
+ android:layout_width="@dimen/icon_size"
+ android:layout_marginStart="0dp"
+ android:layout_marginEnd="10dp"
+ android:layout_marginTop="4dp"
+ android:scaleType="centerInside"/>
+
+ <TextView
+ android:id="@+id/message_textview"
+ android:layout_height="wrap_content"
+ android:layout_width="wrap_content"
+ android:layout_toEndOf="@+id/message_icon"
+ android:layout_marginStart="0dp"
+ android:layout_marginEnd="8dp"
+ android:layout_marginTop="12dp"
+ android:selectAllOnFocus="true"/>
+
+ <Button
+ android:id="@+id/button_dismiss"
+ android:layout_height="wrap_content"
+ android:layout_width="wrap_content"
+ android:layout_alignEnd="@+id/message_textview"
+ android:layout_below="@+id/message_textview"
+ android:text="@android:string/ok"
+ style="@style/DialogTextButton"/>
+ </RelativeLayout>
+</com.google.android.material.card.MaterialCardView>
diff --git a/res/layout/item_doc_header_message.xml b/res/layout/item_doc_header_message.xml
index 63766a2..9b797ad 100644
--- a/res/layout/item_doc_header_message.xml
+++ b/res/layout/item_doc_header_message.xml
@@ -13,35 +13,52 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:animateLayoutChanges="true"
- android:id="@+id/message_container"
- android:layout_height="wrap_content"
+<com.google.android.material.card.MaterialCardView
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
- android:minHeight="?android:attr/listPreferredItemHeightSmall">
+ android:layout_height="wrap_content"
+ android:layout_margin="4dp"
+ android:elevation="0dp"
+ android:duplicateParentState="true"
+ app:cardElevation="0dp"
+ app:strokeWidth="1dp"
+ app:strokeColor="?android:strokeColor">
- <ImageView
- android:contentDescription="@null"
- android:id="@+id/message_icon"
- android:layout_height="@dimen/icon_size"
- android:layout_width="@dimen/icon_size"
- android:layout_marginStart="0dp"
- android:layout_marginEnd="@dimen/list_item_padding"
- android:scaleType="centerInside"/>
-
- <TextView
- android:id="@+id/message_textview"
+ <RelativeLayout
+ android:animateLayoutChanges="true"
+ android:id="@+id/message_container"
android:layout_height="wrap_content"
- android:layout_width="wrap_content"
- android:layout_toEndOf="@+id/message_icon"
- android:selectAllOnFocus="true"/>
+ android:layout_width="match_parent"
+ android:minHeight="?android:attr/listPreferredItemHeightSmall">
- <Button
- android:id="@+id/button_dismiss"
- android:layout_height="wrap_content"
- android:layout_width="wrap_content"
- android:layout_alignEnd="@+id/message_textview"
- android:layout_below="@+id/message_textview"
- android:text="@android:string/ok"
- style="?attr/materialButtonStyle"/>
-</RelativeLayout>
+ <ImageView
+ android:contentDescription="@null"
+ android:id="@+id/message_icon"
+ android:layout_height="@dimen/icon_size"
+ android:layout_width="@dimen/icon_size"
+ android:layout_marginStart="0dp"
+ android:layout_marginEnd="10dp"
+ android:layout_marginTop="4dp"
+ android:scaleType="centerInside"/>
+
+ <TextView
+ android:id="@+id/message_textview"
+ android:layout_height="wrap_content"
+ android:layout_width="wrap_content"
+ android:layout_toEndOf="@+id/message_icon"
+ android:layout_marginStart="0dp"
+ android:layout_marginEnd="8dp"
+ android:layout_marginTop="12dp"
+ android:selectAllOnFocus="true"/>
+
+ <Button
+ android:id="@+id/button_dismiss"
+ android:layout_height="wrap_content"
+ android:layout_width="wrap_content"
+ android:layout_alignEnd="@+id/message_textview"
+ android:layout_below="@+id/message_textview"
+ android:text="@android:string/ok"
+ style="@style/DialogTextButton"/>
+ </RelativeLayout>
+</com.google.android.material.card.MaterialCardView>
diff --git a/src/com/android/documentsui/picker/ActionHandler.java b/src/com/android/documentsui/picker/ActionHandler.java
index ef16e6d..e9868df 100644
--- a/src/com/android/documentsui/picker/ActionHandler.java
+++ b/src/com/android/documentsui/picker/ActionHandler.java
@@ -23,6 +23,7 @@
import static com.android.documentsui.base.State.ACTION_OPEN_TREE;
import static com.android.documentsui.base.State.ACTION_PICK_COPY_DESTINATION;
+import android.content.ActivityNotFoundException;
import android.content.ClipData;
import android.content.ComponentName;
import android.content.Intent;
@@ -218,7 +219,7 @@
mInjector.pickResult.setIsSearching(isSearching);
mInjector.pickResult.setRoot(root);
mInjector.pickResult.setFileUri(uri);
- getUpdatePickResultTask().execute();
+ getUpdatePickResultTask().safeExecute();
}
private void loadDefaultLocation() {
@@ -298,7 +299,12 @@
intent.setFlags(intent.getFlags() & ~Intent.FLAG_ACTIVITY_FORWARD_RESULT);
intent.setComponent(new ComponentName(
info.activityInfo.applicationInfo.packageName, info.activityInfo.name));
- mActivity.startActivityForResult(intent, CODE_FORWARD);
+ try {
+ mActivity.startActivityForResult(intent, CODE_FORWARD);
+ } catch (SecurityException | ActivityNotFoundException e) {
+ Log.e(TAG, "Caught error: " + e.getLocalizedMessage());
+ mInjector.dialogs.showNoApplicationFound();
+ }
}
@Override
diff --git a/src/com/android/documentsui/picker/PickActivity.java b/src/com/android/documentsui/picker/PickActivity.java
index 57969e0..7736077 100644
--- a/src/com/android/documentsui/picker/PickActivity.java
+++ b/src/com/android/documentsui/picker/PickActivity.java
@@ -151,7 +151,7 @@
public void onBackPressed() {
super.onBackPressed();
// log the case of user picking nothing.
- mInjector.actions.getUpdatePickResultTask().execute();
+ mInjector.actions.getUpdatePickResultTask().safeExecute();
}
@Override
diff --git a/src/com/android/documentsui/picker/UpdatePickResultTask.java b/src/com/android/documentsui/picker/UpdatePickResultTask.java
index ff35137..43f42ab 100644
--- a/src/com/android/documentsui/picker/UpdatePickResultTask.java
+++ b/src/com/android/documentsui/picker/UpdatePickResultTask.java
@@ -20,6 +20,7 @@
import android.net.Uri;
import android.os.AsyncTask;
import android.os.SystemClock;
+
import com.android.documentsui.Metrics;
// load & update mime type & repeatedly pick count in background
@@ -62,4 +63,12 @@
Metrics.logPickResult(mPickResult);
}
+ /**
+ * Check the status and only execute if task is pending.
+ */
+ public void safeExecute() {
+ if (getStatus() == Status.PENDING) {
+ execute();
+ }
+ }
}
diff --git a/src/com/android/documentsui/sidebar/RootsFragment.java b/src/com/android/documentsui/sidebar/RootsFragment.java
index 4d40bbc..4db65f3 100644
--- a/src/com/android/documentsui/sidebar/RootsFragment.java
+++ b/src/com/android/documentsui/sidebar/RootsFragment.java
@@ -355,6 +355,13 @@
// Omit ourselves and maybe calling package from the list
for (ResolveInfo info : infos) {
+ if (!info.activityInfo.exported) {
+ if (VERBOSE) {
+ Log.v(TAG, "Non exported activity: " + info.activityInfo);
+ }
+ continue;
+ }
+
final String packageName = info.activityInfo.packageName;
if (!context.getPackageName().equals(packageName) &&
!TextUtils.equals(excludePackage, packageName)) {
diff --git a/tests/unit/com/android/documentsui/picker/UpdatePickResultTaskTest.java b/tests/unit/com/android/documentsui/picker/UpdatePickResultTaskTest.java
new file mode 100644
index 0000000..4c2fb89
--- /dev/null
+++ b/tests/unit/com/android/documentsui/picker/UpdatePickResultTaskTest.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2019 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.picker;
+
+import android.content.Context;
+
+import androidx.test.InstrumentationRegistry;
+import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class UpdatePickResultTaskTest {
+
+ private UpdatePickResultTask mTask;
+
+ @Before
+ public void setUp() {
+ Context context = InstrumentationRegistry.getInstrumentation().getTargetContext();
+ mTask = new UpdatePickResultTask(context, new PickResult());
+ }
+
+ @Test
+ public void testSafeExcute_noCrash() throws Exception {
+ mTask.safeExecute();
+ mTask.safeExecute();
+ }
+}