blob: 30ac4c22789c12c8558457effafa3be76f5ce871 [file] [log] [blame]
// Copyright 2021 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package org.chromium.chrome.browser.content_creation.notes;
import android.app.Activity;
import android.content.ComponentName;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.os.Build;
import android.view.View;
import androidx.fragment.app.FragmentActivity;
import org.chromium.chrome.browser.content_creation.internal.R;
import org.chromium.chrome.browser.content_creation.notes.fonts.GoogleFontService;
import org.chromium.chrome.browser.content_creation.notes.images.ImageService;
import org.chromium.chrome.browser.content_creation.notes.top_bar.TopBarCoordinator;
import org.chromium.chrome.browser.content_creation.notes.top_bar.TopBarDelegate;
import org.chromium.chrome.browser.profiles.Profile;
import org.chromium.chrome.browser.share.ChromeShareExtras;
import org.chromium.chrome.browser.share.share_sheet.ChromeOptionShareCallback;
import org.chromium.chrome.browser.tab.Tab;
import org.chromium.components.browser_ui.share.ShareImageFileUtils;
import org.chromium.components.browser_ui.share.ShareParams;
import org.chromium.components.content_creation.notes.NoteService;
import org.chromium.components.image_fetcher.ImageFetcher;
import org.chromium.components.image_fetcher.ImageFetcherConfig;
import org.chromium.components.image_fetcher.ImageFetcherFactory;
import org.chromium.components.url_formatter.UrlFormatter;
import org.chromium.ui.modelutil.MVCListAdapter.ModelList;
import java.text.DateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.Locale;
/**
* Responsible for notes main UI and its subcomponents.
*/
public class NoteCreationCoordinatorImpl implements NoteCreationCoordinator, TopBarDelegate {
private static final String PNG_MIME_TYPE = "image/PNG";
private final Activity mActivity;
private final Tab mTab;
private final ModelList mListModel;
private final NoteCreationMediator mMediator;
private final NoteCreationDialog mDialog;
private final ChromeOptionShareCallback mChromeOptionShareCallback;
private final String mShareUrl;
private final String mSelectedText;
private long mCreationStartTime;
private TopBarCoordinator mTopBarCoordinator;
public NoteCreationCoordinatorImpl(Activity activity, Tab tab, NoteService noteService,
ChromeOptionShareCallback chromeOptionShareCallback, String shareUrl, String title,
String selectedText) {
mActivity = activity;
mTab = tab;
mChromeOptionShareCallback = chromeOptionShareCallback;
mShareUrl = shareUrl;
mSelectedText = selectedText;
selectedText = addQuotes(selectedText);
mListModel = new ModelList();
Profile profile = Profile.fromWebContents(tab.getWebContents());
ImageFetcher imageFetcher = ImageFetcherFactory.createImageFetcher(
ImageFetcherConfig.DISK_CACHE_ONLY, profile.getProfileKey());
mMediator = new NoteCreationMediator(mListModel, new GoogleFontService(mActivity),
noteService, new ImageService(imageFetcher));
String urlDomain =
UrlFormatter.formatUrlForDisplayOmitSchemeOmitTrivialSubdomains(mShareUrl);
mDialog = new NoteCreationDialog();
mDialog.initDialog(this::onViewCreated, urlDomain, title, selectedText,
noteService.isPublishAvailable());
}
@Override
public void showDialog() {
mCreationStartTime = System.currentTimeMillis();
NoteCreationMetrics.recordNoteCreationSelected();
FragmentActivity fragmentActivity = (FragmentActivity) mActivity;
mDialog.show(fragmentActivity.getSupportFragmentManager(), null);
}
/**
* Dismiss the main dialog.
*/
@Override
public void dismiss() {
NoteCreationMetrics.recordNoteCreationDismissed(getTimeElapsedSinceCreationStart());
NoteCreationMetrics.recordNbTemplateChanges(mDialog.getNbTemplateSwitches());
mDialog.dismiss();
}
/**
* Publish the selected note
*/
@Override
public void publish() {
mMediator.publishNote(mSelectedText, mShareUrl, this::resolvePublishedNote);
}
/**
* Share the currently selected note.
*/
@Override
public void executeAction() {
NoteCreationMetrics.recordNoteTemplateSelected(getTimeElapsedSinceCreationStart());
NoteCreationMetrics.recordNbTemplateChanges(mDialog.getNbTemplateSwitches());
int selectedNoteIndex = mDialog.getSelectedItemIndex();
NoteCreationMetrics.recordSelectedTemplateId(
mListModel.get(selectedNoteIndex).model.get(NoteProperties.TEMPLATE).id);
View noteView = mDialog.getNoteViewAt(selectedNoteIndex);
assert noteView != null;
Bitmap bitmap = Bitmap.createBitmap(
noteView.getWidth(), noteView.getHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
noteView.draw(canvas);
ShareImageFileUtils.generateTemporaryUriFromBitmap(
getNoteFilenamePrefix(), bitmap, (imageUri) -> {
final String sheetTitle = getShareSheetTitle();
ShareParams params =
new ShareParams.Builder(mTab.getWindowAndroid(), sheetTitle, mShareUrl)
.setFileUris(
new ArrayList<>(Collections.singletonList(imageUri)))
.setFileContentType(PNG_MIME_TYPE)
.setCallback(new ShareParams.TargetChosenCallback() {
@Override
public void onTargetChosen(ComponentName chosenComponent) {
NoteCreationMetrics.recordNoteShared(
getTimeElapsedSinceCreationStart());
}
@Override
public void onCancel() {
NoteCreationMetrics.recordNoteNotShared(
getTimeElapsedSinceCreationStart());
}
})
.build();
long shareStartTime = System.currentTimeMillis();
ChromeShareExtras extras =
new ChromeShareExtras.Builder().setSkipPageSharingActions(true).build();
// Dismiss current dialog before showing the share sheet.
this.dismiss();
mChromeOptionShareCallback.showShareSheet(params, extras, shareStartTime);
});
}
/**
* Initializes the top bar after the parent view is ready.
* @param view A {@link View} to corresponding to the parent view for the top bar.
*/
private void onViewCreated(View view) {
mTopBarCoordinator = new TopBarCoordinator(mActivity, view, this);
mDialog.createRecyclerViews(mListModel);
}
/**
* Returns the localized temporary filename's prefix. Random numbers will be
* appended to it when the file creation happens.
*/
private String getNoteFilenamePrefix() {
return mActivity.getString(R.string.content_creation_note_filename_prefix);
}
/**
* Creates the share sheet title based on a localized title format and the
* current date formatted for the user's preferred locale.
*/
private String getShareSheetTitle() {
Date now = new Date(System.currentTimeMillis());
String currentDateString =
DateFormat.getDateInstance(DateFormat.SHORT, getPreferredLocale()).format(now);
return mActivity.getString(
R.string.content_creation_note_title_for_share, currentDateString);
}
/**
* Retrieves the user's preferred locale from the app's configurations.
*/
private Locale getPreferredLocale() {
return Build.VERSION.SDK_INT >= Build.VERSION_CODES.N
? mActivity.getResources().getConfiguration().getLocales().get(0)
: mActivity.getResources().getConfiguration().locale;
}
private String addQuotes(String text) {
// Split localized strings as prefix and suffix instead of full format
// in case they are needed as split later.
return new StringBuilder()
.append(mActivity.getString(R.string.quotation_mark_prefix))
.append(text)
.append(mActivity.getString(R.string.quotation_mark_suffix))
.toString();
}
/**
* Starts the sharing flow for the newly published note.
* @param noteUrl The url where the new note can be accessed.
*/
private void resolvePublishedNote(String noteUrl) {
final String sheetTitle = getShareSheetTitle();
ShareParams params =
new ShareParams.Builder(mTab.getWindowAndroid(), sheetTitle, noteUrl).build();
long shareStartTime = System.currentTimeMillis();
ChromeShareExtras extras =
new ChromeShareExtras.Builder().setSkipPageSharingActions(true).build();
// Dismiss current dialog before showing the share sheet.
this.dismiss();
mChromeOptionShareCallback.showShareSheet(params, extras, shareStartTime);
}
/**
* Returns the time elapsed since the creation was started.
*/
private long getTimeElapsedSinceCreationStart() {
return System.currentTimeMillis() - mCreationStartTime;
}
}