blob: a0fefa67df402ebc0405f29dbdba15ab72c64d87 [file] [log] [blame]
// Copyright 2017 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.language.settings;
import androidx.annotation.IntDef;
import org.chromium.base.metrics.RecordHistogram;
import org.chromium.chrome.browser.translate.TranslateBridge;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
/**
* Manages languages details for languages settings.
*
*The LanguagesManager is responsible for fetching languages details from native.
*/
public class LanguagesManager {
/**
* An observer interface that allows other classes to know when the accept language list is
* updated in native side.
*/
interface AcceptLanguageObserver {
/**
* Called when the accept languages for the current user are updated.
*/
void onDataUpdated();
}
// Constants used to log UMA enum histogram, must stay in sync with
// LanguageSettingsActionType. Further actions can only be appended, existing
// entries must not be overwritten.
@IntDef({LanguageSettingsActionType.CLICK_ON_ADD_LANGUAGE,
LanguageSettingsActionType.LANGUAGE_ADDED, LanguageSettingsActionType.LANGUAGE_REMOVED,
LanguageSettingsActionType.DISABLE_TRANSLATE_GLOBALLY,
LanguageSettingsActionType.ENABLE_TRANSLATE_GLOBALLY,
LanguageSettingsActionType.DISABLE_TRANSLATE_FOR_SINGLE_LANGUAGE,
LanguageSettingsActionType.ENABLE_TRANSLATE_FOR_SINGLE_LANGUAGE,
LanguageSettingsActionType.LANGUAGE_LIST_REORDERED})
@Retention(RetentionPolicy.SOURCE)
@interface LanguageSettingsActionType {
int CLICK_ON_ADD_LANGUAGE = 1;
int LANGUAGE_ADDED = 2;
int LANGUAGE_REMOVED = 3;
int DISABLE_TRANSLATE_GLOBALLY = 4;
int ENABLE_TRANSLATE_GLOBALLY = 5;
int DISABLE_TRANSLATE_FOR_SINGLE_LANGUAGE = 6;
int ENABLE_TRANSLATE_FOR_SINGLE_LANGUAGE = 7;
int LANGUAGE_LIST_REORDERED = 8;
int NUM_ENTRIES = 9;
}
// Constants used to log UMA enum histogram, must stay in sync with
// LanguageSettingsPageType. Further actions can only be appended, existing
// entries must not be overwritten.
@IntDef({LanguageSettingsPageType.PAGE_MAIN, LanguageSettingsPageType.PAGE_ADD_LANGUAGE})
@Retention(RetentionPolicy.SOURCE)
@interface LanguageSettingsPageType {
int PAGE_MAIN = 0;
int PAGE_ADD_LANGUAGE = 1;
int NUM_ENTRIES = 2;
}
private static LanguagesManager sManager;
private final Map<String, LanguageItem> mLanguagesMap;
private AcceptLanguageObserver mObserver;
private LanguagesManager() {
// Get all language data from native.
mLanguagesMap = new LinkedHashMap<>();
for (LanguageItem item : TranslateBridge.getChromeLanguageList()) {
mLanguagesMap.put(item.getCode(), item);
}
}
private void notifyAcceptLanguageObserver() {
if (mObserver != null) mObserver.onDataUpdated();
}
/**
* Sets the observer tracking the user accept languages changes.
*/
public void setAcceptLanguageObserver(AcceptLanguageObserver observer) {
mObserver = observer;
}
/**
* @return A list of LanguageItems for the current user's accept languages.
*/
public List<LanguageItem> getUserAcceptLanguageItems() {
// Always read the latest user accept language code list from native.
List<String> codes = TranslateBridge.getUserLanguageCodes();
List<LanguageItem> results = new ArrayList<>();
// Keep the same order as accept language codes list.
for (String code : codes) {
// Check language code and only languages supported on Android are added in.
if (mLanguagesMap.containsKey(code)) results.add(mLanguagesMap.get(code));
}
return results;
}
/**
* @return A list of LanguageItems, excluding the current user's accept languages.
*/
public List<LanguageItem> getLanguageItemsExcludingUserAccept() {
// Always read the latest user accept language code list from native.
List<String> codes = TranslateBridge.getUserLanguageCodes();
List<LanguageItem> results = new ArrayList<>();
// Keep the same order as mLanguagesMap.
for (LanguageItem item : mLanguagesMap.values()) {
if (!codes.contains(item.getCode())) results.add(item);
}
return results;
}
/**
* Add a language to the current user's accept languages.
* @param code The language code to remove.
*/
public void addToAcceptLanguages(String code) {
TranslateBridge.updateUserAcceptLanguages(code, true /* is_add */);
notifyAcceptLanguageObserver();
}
/**
* Remove a language from the current user's accept languages.
* @param code The language code to remove.
*/
public void removeFromAcceptLanguages(String code) {
TranslateBridge.updateUserAcceptLanguages(code, false /* is_add */);
notifyAcceptLanguageObserver();
}
/**
* Move a language's position in the user's accept languages list.
* @param code The language code to move.
* @param offset The offset from the original position.
* Negative value means up and positive value means down.
* @param reload Whether to reload the language list.
*/
public void moveLanguagePosition(String code, int offset, boolean reload) {
if (offset == 0) return;
TranslateBridge.moveAcceptLanguage(code, offset);
recordAction(LanguageSettingsActionType.LANGUAGE_LIST_REORDERED);
if (reload) notifyAcceptLanguageObserver();
}
/**
* Sets the preference order of the user's accepted languages to the provided order.
*
* @param codes The new order for the user's languages.
* @param reload True iff the language list should be reloaded.
*/
public void setOrder(String[] codes, boolean reload) {
TranslateBridge.setLanguageOrder(codes);
recordAction(LanguageSettingsActionType.LANGUAGE_LIST_REORDERED);
if (reload) notifyAcceptLanguageObserver();
}
/**
* Called to get all languages available in chrome.
* @return A map of language code to {@code LanguageItem} for all available languages.
*/
public Map<String, LanguageItem> getLanguageMap() {
return mLanguagesMap;
}
/**
* Get the static instance of ChromePreferenceManager if it exists else create it.
* @return the LanguagesManager singleton.
*/
public static LanguagesManager getInstance() {
if (sManager == null) sManager = new LanguagesManager();
return sManager;
}
/**
* Called to release unused resources.
*/
public static void recycle() {
sManager = null;
}
/**
* Record language settings page impression.
*/
public static void recordImpression(@LanguageSettingsPageType int pageType) {
RecordHistogram.recordEnumeratedHistogram(
"LanguageSettings.PageImpression", pageType, LanguageSettingsPageType.NUM_ENTRIES);
}
/**
* Record actions taken on language settings page.
*/
public static void recordAction(@LanguageSettingsActionType int actionType) {
RecordHistogram.recordEnumeratedHistogram(
"LanguageSettings.Actions", actionType, LanguageSettingsActionType.NUM_ENTRIES);
}
}