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

Commit 456eaedb authored by Tom Hsu's avatar Tom Hsu Committed by Android (Google) Code Review
Browse files

Merge "[Panlingual] Adds a filter of application for per apps locale change."

parents adf5ccf3 33f2096f
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -573,4 +573,14 @@

    <!-- Whether to give option to add restricted profiles -->
    <bool name="config_offer_restricted_profiles">false</bool>

    <!-- An array of packages for which Applications whose per-app locale cannot be changed. -->
    <string-array name="config_disallowed_app_localeChange_packages" translatable="false">
        <!--
        <item>com.example.package.first</item>
        <item>com.example.package.second</item>
        <item>...</item>
        -->
    </string-array>

</resources>
+68 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2022 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.settings.applications;

import android.app.ActivityManager;
import android.content.Context;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.util.Log;

import com.android.settings.R;
import com.android.settingslib.applications.ApplicationsState.AppEntry;

/** This class provides methods that help dealing with per app locale. */
public class AppLocaleUtil {
    private static final String TAG = AppLocaleUtil.class.getSimpleName();

    /**
     * Decides the UI display of per app locale.
     */
    public static boolean canDisplayLocaleUi(Context context, AppEntry app) {
        return !isDisallowedPackage(context, app.info.packageName)
                && !isSignedWithPlatformKey(context, app.info.packageName)
                && app.hasLauncherEntry;
    }

    private static boolean isDisallowedPackage(Context context, String packageName) {
        final String[] disallowedPackages = context.getResources().getStringArray(
                R.array.config_disallowed_app_localeChange_packages);
        for (String disallowedPackage : disallowedPackages) {
            if (packageName.equals(disallowedPackage)) {
                return true;
            }
        }
        return false;
    }

    private static boolean isSignedWithPlatformKey(Context context, String packageName) {
        PackageInfo packageInfo = null;
        PackageManager packageManager = context.getPackageManager();
        ActivityManager activityManager = context.getSystemService(ActivityManager.class);
        try {
            packageInfo = packageManager.getPackageInfoAsUser(
                    packageName, /* flags= */ 0,
                    activityManager.getCurrentUser());
        } catch (PackageManager.NameNotFoundException ex) {
            Log.e(TAG, "package not found: " + packageName);
        }
        if (packageInfo == null) {
            return false;
        }
        return packageInfo.applicationInfo.isSignedWithPlatformKey();
    }
}
+77 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2022 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.android.settings.applications;

import android.content.Context;
import android.util.Log;

import com.android.settingslib.applications.ApplicationsState;
import com.android.settingslib.applications.ApplicationsState.AppEntry;
import com.android.settingslib.applications.ApplicationsState.AppFilter;

import java.util.List;

/**
 * Creates a application filter to restrict UI display of applications.
 * This is to avoid users from changing the per apps locale
 * Also provides app filters that can use the info.
 */
public class AppStateLocaleBridge extends AppStateBaseBridge {
    private static final String TAG = AppStateLocaleBridge.class.getSimpleName();

    private final Context mContext;

    public AppStateLocaleBridge(Context context, ApplicationsState appState,
            Callback callback) {
        super(appState, callback);
        mContext = context;
    }

    @Override
    protected void updateExtraInfo(AppEntry app, String packageName, int uid) {
        app.extraInfo = AppLocaleUtil.canDisplayLocaleUi(mContext, app)
                ? Boolean.TRUE : Boolean.FALSE;
    }

    @Override
    protected void loadAllExtraInfo() {
        final List<AppEntry> allApps = mAppSession.getAllApps();
        for (int i = 0; i < allApps.size(); i++) {
            AppEntry app = allApps.get(i);
            app.extraInfo = AppLocaleUtil.canDisplayLocaleUi(mContext, app)
                    ? Boolean.TRUE : Boolean.FALSE;
        }
    }

    /** For the Settings which shows category of per app's locale. */
    public static final AppFilter FILTER_APPS_LOCALE =
            new AppFilter() {
                @Override
                public void init() {
                }

                @Override
                public boolean filterApp(AppEntry entry) {
                    if (entry.extraInfo == null) {
                        Log.d(TAG, "No extra info.");
                        return false;
                    }
                    return (Boolean) entry.extraInfo;
                }
            };


}
+10 −3
Original line number Diff line number Diff line
@@ -20,20 +20,23 @@ import android.content.Context;
import android.util.FeatureFlagUtils;

import com.android.settings.SettingsPreferenceFragment;
import com.android.settings.applications.AppLocaleUtil;

/**
 * A controller to update current locale information of application.
 */
public class AppLocalePreferenceController extends AppInfoPreferenceControllerBase {
    private static final String TAG = AppLocalePreferenceController.class.getSimpleName();

    public AppLocalePreferenceController(Context context, String key) {
        super(context, key);
    }

    @Override
    public int getAvailabilityStatus() {
        return FeatureFlagUtils
                .isEnabled(mContext, FeatureFlagUtils.SETTINGS_APP_LANGUAGE_SELECTION)
                ? AVAILABLE : CONDITIONALLY_UNAVAILABLE;
        boolean isFeatureOn = FeatureFlagUtils
                .isEnabled(mContext, FeatureFlagUtils.SETTINGS_APP_LANGUAGE_SELECTION);
        return isFeatureOn && canDisplayLocaleUi() ? AVAILABLE : CONDITIONALLY_UNAVAILABLE;
    }

    @Override
@@ -45,4 +48,8 @@ public class AppLocalePreferenceController extends AppInfoPreferenceControllerBa
    public CharSequence getSummary() {
        return AppLocaleDetails.getSummary(mContext, mParent.getAppEntry().info.packageName);
    }

    boolean canDisplayLocaleUi() {
        return AppLocaleUtil.canDisplayLocaleUi(mContext, mParent.getAppEntry());
    }
}
+15 −2
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@ import androidx.annotation.IntDef;
import com.android.settings.R;
import com.android.settings.applications.AppStateAlarmsAndRemindersBridge;
import com.android.settings.applications.AppStateInstallAppsBridge;
import com.android.settings.applications.AppStateLocaleBridge;
import com.android.settings.applications.AppStateManageExternalStorageBridge;
import com.android.settings.applications.AppStateMediaManagementAppsBridge;
import com.android.settings.applications.AppStateNotificationBridge;
@@ -54,6 +55,7 @@ public class AppFilterRegistry {
            FILTER_APPS_BLOCKED,
            FILTER_ALARMS_AND_REMINDERS,
            FILTER_APPS_MEDIA_MANAGEMENT,
            FILTER_APPS_LOCALE,
    })
    @interface FilterType {
    }
@@ -79,14 +81,15 @@ public class AppFilterRegistry {
    public static final int FILTER_MANAGE_EXTERNAL_STORAGE = 17;
    public static final int FILTER_ALARMS_AND_REMINDERS = 18;
    public static final int FILTER_APPS_MEDIA_MANAGEMENT = 19;
    // Next id: 20. If you add an entry here, length of mFilters should be updated
    public static final int FILTER_APPS_LOCALE = 20;
    // Next id: 21. If you add an entry here, length of mFilters should be updated

    private static AppFilterRegistry sRegistry;

    private final AppFilterItem[] mFilters;

    private AppFilterRegistry() {
        mFilters = new AppFilterItem[20];
        mFilters = new AppFilterItem[21];

        // High power allowlist, on
        mFilters[FILTER_APPS_POWER_ALLOWLIST] = new AppFilterItem(
@@ -203,8 +206,16 @@ public class AppFilterRegistry {
                AppStateMediaManagementAppsBridge.FILTER_MEDIA_MANAGEMENT_APPS,
                FILTER_APPS_MEDIA_MANAGEMENT,
                R.string.media_management_apps_title);

        // Apps that can configurate appication's locale.
        mFilters[FILTER_APPS_LOCALE] = new AppFilterItem(
                AppStateLocaleBridge.FILTER_APPS_LOCALE,
            FILTER_APPS_LOCALE,
                R.string.app_locale_picker_title);
    }



    public static AppFilterRegistry getInstance() {
        if (sRegistry == null) {
            sRegistry = new AppFilterRegistry();
@@ -235,6 +246,8 @@ public class AppFilterRegistry {
                return FILTER_ALARMS_AND_REMINDERS;
            case ManageApplications.LIST_TYPE_MEDIA_MANAGEMENT_APPS:
                return FILTER_APPS_MEDIA_MANAGEMENT;
            case ManageApplications.LIST_TYPE_APPS_LOCALE:
                return FILTER_APPS_LOCALE;
            default:
                return FILTER_APPS_ALL;
        }
Loading