diff options
7 files changed, 161 insertions, 61 deletions
diff --git a/res/layout-sw720dp/item_doc_header_message.xml b/res/layout-sw720dp/item_doc_header_message.xml index efec111e8..9b797ad70 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"> - - <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"/> + 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"> - <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 63766a2e2..9b797ad70 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"> - - <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"/> + 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"> - <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 ef16e6d4a..e9868df04 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; 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 @@ class ActionHandler<T extends FragmentActivity & Addons> extends AbstractActionH mInjector.pickResult.setIsSearching(isSearching); mInjector.pickResult.setRoot(root); mInjector.pickResult.setFileUri(uri); - getUpdatePickResultTask().execute(); + getUpdatePickResultTask().safeExecute(); } private void loadDefaultLocation() { @@ -298,7 +299,12 @@ class ActionHandler<T extends FragmentActivity & Addons> extends AbstractActionH 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 57969e0c2..773607775 100644 --- a/src/com/android/documentsui/picker/PickActivity.java +++ b/src/com/android/documentsui/picker/PickActivity.java @@ -151,7 +151,7 @@ public class PickActivity extends BaseActivity implements ActionHandler.Addons { 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 ff3513779..43f42ab0a 100644 --- a/src/com/android/documentsui/picker/UpdatePickResultTask.java +++ b/src/com/android/documentsui/picker/UpdatePickResultTask.java @@ -20,6 +20,7 @@ import android.content.Context; 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 @@ public class UpdatePickResultTask extends AsyncTask<Void, Void, Void> { 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 4d40bbc43..4db65f37d 100644 --- a/src/com/android/documentsui/sidebar/RootsFragment.java +++ b/src/com/android/documentsui/sidebar/RootsFragment.java @@ -355,6 +355,13 @@ public class RootsFragment extends Fragment { // 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 000000000..4c2fb89ae --- /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(); + } +} |