• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2023 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.intentresolver.contentpreview;
18 
19 import static com.android.intentresolver.util.UriFilters.isOwnedByCurrentUser;
20 
21 import android.content.res.Resources;
22 import android.net.Uri;
23 import android.text.SpannableStringBuilder;
24 import android.text.TextUtils;
25 import android.view.LayoutInflater;
26 import android.view.View;
27 import android.view.ViewGroup;
28 import android.widget.ImageView;
29 import android.widget.TextView;
30 
31 import androidx.annotation.Nullable;
32 
33 import com.android.intentresolver.ContentTypeHint;
34 import com.android.intentresolver.R;
35 import com.android.intentresolver.widget.ActionRow;
36 
37 import kotlinx.coroutines.CoroutineScope;
38 
39 class TextContentPreviewUi extends ContentPreviewUi {
40     private final CoroutineScope mScope;
41     @Nullable
42     private final CharSequence mSharingText;
43     @Nullable
44     private final CharSequence mPreviewTitle;
45     @Nullable
46     private final CharSequence mMetadata;
47     @Nullable
48     private final Uri mPreviewThumbnail;
49     private final ImageLoader mImageLoader;
50     private final ChooserContentPreviewUi.ActionFactory mActionFactory;
51     private final HeadlineGenerator mHeadlineGenerator;
52     private final ContentTypeHint mContentTypeHint;
53 
TextContentPreviewUi( CoroutineScope scope, @Nullable CharSequence sharingText, @Nullable CharSequence previewTitle, @Nullable CharSequence metadata, @Nullable Uri previewThumbnail, ChooserContentPreviewUi.ActionFactory actionFactory, ImageLoader imageLoader, HeadlineGenerator headlineGenerator, ContentTypeHint contentTypeHint)54     TextContentPreviewUi(
55             CoroutineScope scope,
56             @Nullable CharSequence sharingText,
57             @Nullable CharSequence previewTitle,
58             @Nullable CharSequence metadata,
59             @Nullable Uri previewThumbnail,
60             ChooserContentPreviewUi.ActionFactory actionFactory,
61             ImageLoader imageLoader,
62             HeadlineGenerator headlineGenerator,
63             ContentTypeHint contentTypeHint) {
64         mScope = scope;
65         mSharingText = sharingText;
66         mPreviewTitle = previewTitle;
67         mMetadata = metadata;
68         mPreviewThumbnail = previewThumbnail;
69         mImageLoader = imageLoader;
70         mActionFactory = actionFactory;
71         mHeadlineGenerator = headlineGenerator;
72         mContentTypeHint = contentTypeHint;
73     }
74 
75     @Override
getType()76     public int getType() {
77         return ContentPreviewType.CONTENT_PREVIEW_TEXT;
78     }
79 
80     @Override
display( Resources resources, LayoutInflater layoutInflater, ViewGroup parent, View headlineViewParent)81     public ViewGroup display(
82             Resources resources,
83             LayoutInflater layoutInflater,
84             ViewGroup parent,
85             View headlineViewParent) {
86         return displayInternal(layoutInflater, parent, headlineViewParent);
87     }
88 
displayInternal( LayoutInflater layoutInflater, ViewGroup parent, View headlineViewParent)89     private ViewGroup displayInternal(
90             LayoutInflater layoutInflater,
91             ViewGroup parent,
92             View headlineViewParent) {
93         ViewGroup contentPreviewLayout = (ViewGroup) layoutInflater.inflate(
94                 R.layout.chooser_grid_preview_text, parent, false);
95         inflateHeadline(headlineViewParent);
96 
97         final ActionRow actionRow =
98                 contentPreviewLayout.findViewById(com.android.internal.R.id.chooser_action_row);
99         actionRow.setActions(mActionFactory.createCustomActions());
100 
101         if (mSharingText == null) {
102             contentPreviewLayout
103                     .findViewById(R.id.text_preview_layout)
104                     .setVisibility(View.GONE);
105             return contentPreviewLayout;
106         }
107 
108         TextView textView = contentPreviewLayout.findViewById(
109                 com.android.internal.R.id.content_preview_text);
110 
111         textView.setText(
112                 textView.getMaxLines() == 1 ? replaceLineBreaks(mSharingText) : mSharingText);
113 
114         TextView previewTitleView = contentPreviewLayout.findViewById(
115                 com.android.internal.R.id.content_preview_title);
116         if (TextUtils.isEmpty(mPreviewTitle)) {
117             previewTitleView.setVisibility(View.GONE);
118         } else {
119             previewTitleView.setText(mPreviewTitle);
120         }
121 
122         ImageView previewThumbnailView = contentPreviewLayout.findViewById(
123                 com.android.internal.R.id.content_preview_thumbnail);
124         if (!isOwnedByCurrentUser(mPreviewThumbnail)) {
125             previewThumbnailView.setVisibility(View.GONE);
126         } else {
127             mImageLoader.loadImage(
128                     mScope,
129                     mPreviewThumbnail,
130                     (bitmap) -> updateViewWithImage(
131                             contentPreviewLayout.findViewById(
132                                     com.android.internal.R.id.content_preview_thumbnail),
133                             bitmap));
134         }
135 
136         Runnable onCopy = mActionFactory.getCopyButtonRunnable();
137         View copyButton = contentPreviewLayout.findViewById(R.id.copy);
138         if (onCopy != null) {
139             copyButton.setOnClickListener((v) -> onCopy.run());
140         } else {
141             copyButton.setVisibility(View.GONE);
142         }
143 
144         String headlineText = (mContentTypeHint == ContentTypeHint.ALBUM)
145                 ? mHeadlineGenerator.getAlbumHeadline()
146                 : mHeadlineGenerator.getTextHeadline(mSharingText);
147         displayHeadline(headlineViewParent, headlineText);
148         displayMetadata(headlineViewParent, mMetadata);
149 
150         return contentPreviewLayout;
151     }
152 
153     @Nullable
replaceLineBreaks(@ullable CharSequence text)154     private static CharSequence replaceLineBreaks(@Nullable CharSequence text) {
155         if (text == null) {
156             return null;
157         }
158         SpannableStringBuilder string = new SpannableStringBuilder(text);
159         for (int i = 0, size = string.length(); i < size; i++) {
160             if (string.charAt(i) == '\n') {
161                 string.replace(i, i + 1, " ");
162             }
163         }
164         return string;
165     }
166 }
167