blob: ef7ffde9d21f99f08e9b9fb7fe6792607afbb75a [file] [log] [blame]
// Copyright 2018 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.autofill_assistant;
import android.support.annotation.Nullable;
import org.json.JSONObject;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
/**
* Java side equivalent of autofill_assistant::DetailsProto.
*/
class Details {
enum DetailsField { TITLE, URL, DATE, DESCRIPTION, IS_FINAL }
private final String mTitle;
private final String mUrl;
@Nullable
private final Date mDate;
private final String mDescription;
private final boolean mIsFinal;
/** Contains the fields that have changed when merging with other Details object. */
private final Set<DetailsField> mFieldsChanged;
// NOTE: When adding a new field, update the isEmpty method.
static final Details EMPTY_DETAILS =
new Details("", "", null, "", false, Collections.emptySet());
private static final String RFC_3339_FORMAT_WITHOUT_TIMEZONE = "yyyy'-'MM'-'dd'T'HH':'mm':'ss";
Details(String title, String url, @Nullable Date date, String description, boolean isFinal,
Set<DetailsField> fieldsChanged) {
this.mTitle = title;
this.mUrl = url;
this.mDate = date;
this.mDescription = description;
this.mIsFinal = isFinal;
this.mFieldsChanged = fieldsChanged;
}
String getTitle() {
return mTitle;
}
String getUrl() {
return mUrl;
}
@Nullable
Date getDate() {
return mDate;
}
String getDescription() {
return mDescription;
}
JSONObject toJSONObject() {
// Details are part of the feedback form, hence they need a JSON representation.
Map<String, String> movieDetails = new HashMap<>();
movieDetails.put("title", mTitle);
movieDetails.put("url", mUrl);
if (mDate != null) movieDetails.put("date", mDate.toString());
movieDetails.put("description", mDescription);
return new JSONObject(movieDetails);
}
/**
* Whether the details are not subject to change anymore. If set to false the animated
* placeholders will be displayed in place of missing data.
*/
boolean isFinal() {
return mIsFinal;
}
Set<DetailsField> getFieldsChanged() {
return mFieldsChanged;
}
boolean isEmpty() {
return mTitle.isEmpty() && mUrl.isEmpty() && mDescription.isEmpty() && mDate == null;
}
// TODO(crbug.com/806868): Create a fallback when there are no parameters for details.
static Details makeFromParameters(Map<String, String> parameters) {
String title = "";
String description = "";
Date date = null;
for (String key : parameters.keySet()) {
if (key.contains("E_NAME")) {
title = parameters.get(key);
continue;
}
if (key.contains("R_NAME")) {
description = parameters.get(key);
continue;
}
if (key.contains("DATETIME")) {
try {
// The parameter contains the timezone shift from the current location, that we
// don't care about.
date = new SimpleDateFormat(RFC_3339_FORMAT_WITHOUT_TIMEZONE, Locale.ROOT)
.parse(parameters.get(key));
} catch (ParseException e) {
// Ignore.
}
}
}
return new Details(title, /* url= */ "", date, description, /* isFinal= */ false,
/* fieldsChanged= */ Collections.emptySet());
}
/**
* Merges {@param oldDetails} with the {@param newDetails} filling the missing fields.
*
* <p>The distinction is important, as the fields from old version take precedence, with the
* exception of date and isFinal fields.
*
* <p>If {@param oldDetails} are empty copy of {@param newDetails} with empty
* {@code changedFields} is returned
*/
static Details merge(Details oldDetails, Details newDetails) {
if (oldDetails.isEmpty()) {
return new Details(newDetails.getTitle(), newDetails.getUrl(), newDetails.getDate(),
newDetails.getDescription(), newDetails.isFinal(), Collections.emptySet());
}
Set<DetailsField> changedFields = new HashSet<>();
// TODO(crbug.com/806868): Change title if mid doesn't match.
String title =
oldDetails.getTitle().isEmpty() ? newDetails.getTitle() : oldDetails.getTitle();
String url = oldDetails.getUrl().isEmpty() ? newDetails.getUrl() : oldDetails.getUrl();
Date date = oldDetails.getDate();
if (newDetails.getDate() != null && oldDetails.getDate() != null
&& !newDetails.getDate().equals(oldDetails.getDate())) {
changedFields.add(DetailsField.DATE);
date = newDetails.getDate();
}
String description = oldDetails.getDescription().isEmpty() ? newDetails.getDescription()
: oldDetails.getDescription();
boolean isFinal = newDetails.isFinal();
return new Details(title, url, date, description, isFinal, changedFields);
}
}