Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 53c97993 authored by Calvin Pan's avatar Calvin Pan Committed by Android (Google) Code Review
Browse files

Merge "Filter the locale not in resources" into tm-dev

parents 3136e202 42bb47de
Loading
Loading
Loading
Loading
+77 −19
Original line number Diff line number Diff line
@@ -20,12 +20,15 @@ import static com.android.internal.app.AppLocaleStore.AppLocaleResult.LocaleStat

import android.app.LocaleConfig;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.InstallSourceInfo;
import android.content.pm.PackageManager;
import android.os.LocaleList;
import android.util.Log;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.Locale;
import java.util.stream.Collectors;

class AppLocaleStore {
    private static final String TAG = AppLocaleStore.class.getSimpleName();
@@ -34,7 +37,8 @@ class AppLocaleStore {
            Context context, String packageName) {
        LocaleConfig localeConfig = null;
        AppLocaleResult.LocaleStatus localeStatus = LocaleStatus.UNKNOWN_FAILURE;
        ArrayList<Locale> appSupportedLocales = new ArrayList<>();
        HashSet<Locale> appSupportedLocales = new HashSet<>();
        HashSet<Locale> assetLocale = getAssetLocales(context, packageName);

        try {
            localeConfig = new LocaleConfig(context.createPackageContext(packageName, 0));
@@ -45,32 +49,43 @@ class AppLocaleStore {
        if (localeConfig != null) {
            if (localeConfig.getStatus() == LocaleConfig.STATUS_SUCCESS) {
                LocaleList packageLocaleList = localeConfig.getSupportedLocales();
                if (packageLocaleList.size() > 0) {
                    localeStatus = LocaleStatus.GET_SUPPORTED_LANGUAGE_FROM_LOCAL_CONFIG;
                boolean shouldFilterNotMatchingLocale = !hasInstallerInfo(context, packageName) &&
                        isSystemApp(context, packageName);

                Log.d(TAG, "filterNonMatchingLocale. " +
                        ", shouldFilterNotMatchingLocale: " + shouldFilterNotMatchingLocale +
                        ", assetLocale size: " + assetLocale.size() +
                        ", packageLocaleList size: " + packageLocaleList.size());

                for (int i = 0; i < packageLocaleList.size(); i++) {
                    appSupportedLocales.add(packageLocaleList.get(i));
                }
                if (shouldFilterNotMatchingLocale) {
                    appSupportedLocales = filterNotMatchingLocale(appSupportedLocales, assetLocale);
                }

                if (appSupportedLocales.size() > 0) {
                    localeStatus = LocaleStatus.GET_SUPPORTED_LANGUAGE_FROM_LOCAL_CONFIG;
                } else {
                    localeStatus = LocaleStatus.NO_SUPPORTED_LANGUAGE_IN_APP;
                }
            } else if (localeConfig.getStatus() == LocaleConfig.STATUS_NOT_SPECIFIED) {
                String[] languages = getAssetLocales(context, packageName);
                if (languages.length > 0) {
                if (assetLocale.size() > 0) {
                    localeStatus = LocaleStatus.GET_SUPPORTED_LANGUAGE_FROM_ASSET;
                    for (String language : languages) {
                        appSupportedLocales.add(Locale.forLanguageTag(language));
                    }
                    appSupportedLocales = assetLocale;
                } else {
                    localeStatus = LocaleStatus.ASSET_LOCALE_IS_EMPTY;
                }
            }
        }
        Log.d(TAG, "getAppSupportedLocales(). status: " + localeStatus
        Log.d(TAG, "getAppSupportedLocales(). package: " + packageName
                + ", status: " + localeStatus
                + ", appSupportedLocales:" + appSupportedLocales.size());
        return new AppLocaleResult(localeStatus, appSupportedLocales);
    }

    private static String[] getAssetLocales(Context context, String packageName) {
    private static HashSet<Locale> getAssetLocales(Context context, String packageName) {
        HashSet<Locale> result = new HashSet<>();
        try {
            PackageManager packageManager = context.getPackageManager();
            String[] locales = packageManager.getResourcesForApplication(
@@ -78,16 +93,59 @@ class AppLocaleStore {
                            .applicationInfo).getAssets().getNonSystemLocales();
            if (locales == null) {
                Log.i(TAG, "[" + packageName + "] locales are null.");
                return new String[0];
            } else if (locales.length <= 0) {
                Log.i(TAG, "[" + packageName + "] locales length is 0.");
                return new String[0];
            } else {
                for (String language : locales) {
                    result.add(Locale.forLanguageTag(language));
                }
            }
            return locales;
        } catch (PackageManager.NameNotFoundException e) {
            Log.w(TAG, "Can not found the package name : " + packageName + " / " + e);
        }
        return new String[0];
        return result;
    }

    private static HashSet<Locale> filterNotMatchingLocale(
            HashSet<Locale> appSupportedLocales, HashSet<Locale> assetLocale) {
        return appSupportedLocales.stream()
                .filter(locale -> matchLanguageInSet(locale, assetLocale))
                .collect(Collectors.toCollection(HashSet::new));
    }

    private static boolean matchLanguageInSet(Locale locale, HashSet<Locale> localesSet) {
        if (localesSet.contains(locale)) {
            return true;
        }
        for (Locale l: localesSet) {
            if(LocaleList.matchesLanguageAndScript(l, locale)) {
                return true;
            }
        }
        return false;
    }

    private static boolean hasInstallerInfo(Context context, String packageName) {
        InstallSourceInfo installSourceInfo;
        try {
            installSourceInfo = context.getPackageManager().getInstallSourceInfo(packageName);
            return installSourceInfo != null;
        } catch (PackageManager.NameNotFoundException e) {
            Log.w(TAG, "Installer info not found for: " + packageName);
        }
        return false;
    }

    private static boolean isSystemApp(Context context, String packageName) {
        ApplicationInfo applicationInfo;
        try {
            applicationInfo = context.getPackageManager()
                    .getApplicationInfoAsUser(packageName, /* flags= */ 0, context.getUserId());
            return applicationInfo.isSystemApp();
        } catch (PackageManager.NameNotFoundException e) {
            Log.w(TAG, "Application info not found for: " + packageName);
        }
        return false;
    }

    static class AppLocaleResult {
@@ -100,9 +158,9 @@ class AppLocaleStore {
        }

        LocaleStatus mLocaleStatus;
        ArrayList<Locale> mAppSupportedLocales;
        HashSet<Locale> mAppSupportedLocales;

        public AppLocaleResult(LocaleStatus localeStatus, ArrayList<Locale> appSupportedLocales) {
        public AppLocaleResult(LocaleStatus localeStatus, HashSet<Locale> appSupportedLocales) {
            this.mLocaleStatus = localeStatus;
            this.mAppSupportedLocales = appSupportedLocales;
        }
+10 −4
Original line number Diff line number Diff line
@@ -36,7 +36,6 @@ import android.widget.SearchView;

import com.android.internal.R;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.Locale;
@@ -204,13 +203,20 @@ public class LocalePickerWithRegion extends ListFragment implements SearchView.O
    }

    private Set<LocaleStore.LocaleInfo> filterTheLanguagesNotSupportedInApp(
            boolean shouldShowList, ArrayList<Locale> supportedLocales) {
            boolean shouldShowList, HashSet<Locale> supportedLocales) {
        Set<LocaleStore.LocaleInfo> filteredList = new HashSet<>();
        if (shouldShowList) {
        if (!shouldShowList) {
            return filteredList;
        }

        for(LocaleStore.LocaleInfo li: mLocaleList) {
            if (supportedLocales.contains(li.getLocale())) {
                filteredList.add(li);
            } else {
                for(Locale l: supportedLocales) {
                    if(LocaleList.matchesLanguageAndScript(li.getLocale(), l)) {
                        filteredList.add(li);
                        break;
                    }
                }
            }