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

Commit 91dad044 authored by Christine Franks's avatar Christine Franks
Browse files

Support DISALLOW_CONFIG_LOCALE user restriction

Bug: 67586452
Test: make ROBOTEST_FILTER="(LocaleListEditorTest)" RunSettingsRoboTests\
&& make cts && cts-tradefed run cts-dev -m DevicePolicyManager \
-t com.android.cts.devicepolicy.UserRestrictionsTest

Change-Id: I2260b106a111078a62ae7628d6f60e976b70069c
parent 538f78c8
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -4057,6 +4057,8 @@
    <!-- Title of setting on main settings screen.  This item will take the user to the screen to tweak settings realted to locale and text -->
    <string name="language_settings">Languages&#160;&amp; input</string>
    <!-- Text displayed when user has restriction DISALLOW_CONFIG_LOCALE [CHAR LIMIT=NONE]-->
    <string name="language_empty_list_user_restricted">You don\u2019t have permission to change the device language.</string>
    <!-- Title of Languages & input settings screen -->
    <string name="language_keyboard_settings_title">Languages&#160;&amp; input</string>
    <!-- Title of preference category that lists all settings about helping user text input such as spell checker [CHAR LIMIT=60]-->
+3 −13
Original line number Diff line number Diff line
@@ -82,14 +82,13 @@ class LocaleDragAndDropAdapter
    }

    public LocaleDragAndDropAdapter(Context context, List<LocaleStore.LocaleInfo> feedItemList) {
        this.mFeedItemList = feedItemList;

        this.mContext = context;
        mFeedItemList = feedItemList;
        mContext = context;

        final float dragElevation = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 8,
                context.getResources().getDisplayMetrics());

        this.mItemTouchHelper = new ItemTouchHelper(new ItemTouchHelper.SimpleCallback(
        mItemTouchHelper = new ItemTouchHelper(new ItemTouchHelper.SimpleCallback(
                ItemTouchHelper.UP | ItemTouchHelper.DOWN, 0 /* no swipe */) {

            @Override
@@ -248,15 +247,6 @@ class LocaleDragAndDropAdapter
        return result;
    }

    LocaleStore.LocaleInfo getFirstChecked() {
        for (LocaleStore.LocaleInfo li : mFeedItemList) {
            if (li.getChecked()) {
                return li;
            }
        }
        return null;
    }

    void addLocale(LocaleStore.LocaleInfo li) {
        mFeedItemList.add(li);
        notifyItemInserted(mFeedItemList.size() - 1);
+34 −9
Original line number Diff line number Diff line
@@ -18,7 +18,6 @@ package com.android.settings.localepicker;

import android.app.AlertDialog;
import android.app.FragmentTransaction;
import android.content.Context;
import android.content.DialogInterface;
import android.os.Bundle;
import android.os.LocaleList;
@@ -30,21 +29,24 @@ import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;

import android.widget.TextView;
import com.android.internal.app.LocalePicker;
import com.android.internal.app.LocalePickerWithRegion;
import com.android.internal.app.LocaleStore;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.settings.R;
import com.android.settings.SettingsPreferenceFragment;
import com.android.settings.RestrictedSettingsFragment;

import java.util.ArrayList;
import java.util.List;
import java.util.Locale;

import static android.os.UserManager.DISALLOW_CONFIG_LOCALE;

/**
 * Drag-and-drop editor for the user-ordered locale lists.
 */
public class LocaleListEditor extends SettingsPreferenceFragment
public class LocaleListEditor extends RestrictedSettingsFragment
        implements LocalePickerWithRegion.LocaleSelectedListener {

    private static final String CFGKEY_REMOVE_MODE = "localeRemoveMode";
@@ -56,6 +58,11 @@ public class LocaleListEditor extends SettingsPreferenceFragment
    private View mAddLanguage;
    private boolean mRemoveMode;
    private boolean mShowingRemoveDialog;
    private boolean mIsUiRestricted;

    public LocaleListEditor() {
        super(DISALLOW_CONFIG_LOCALE);
    }

    @Override
    public int getMetricsCategory() {
@@ -68,7 +75,7 @@ public class LocaleListEditor extends SettingsPreferenceFragment
        setHasOptionsMenu(true);

        LocaleStore.fillCache(this.getContext());
        final List<LocaleStore.LocaleInfo> feedsList = getUserLocaleList(this.getContext());
        final List<LocaleStore.LocaleInfo> feedsList = getUserLocaleList();
        mAdapter = new LocaleDragAndDropAdapter(this.getContext(), feedsList);
    }

@@ -81,6 +88,25 @@ public class LocaleListEditor extends SettingsPreferenceFragment
        return result;
    }

    @Override
    public void onResume() {
        super.onResume();

        final boolean previouslyRestricted = mIsUiRestricted;
        mIsUiRestricted = isUiRestricted();
        final TextView emptyView = getEmptyTextView();
        if (mIsUiRestricted && !previouslyRestricted) {
            // Lock it down.
            emptyView.setText(R.string.language_empty_list_user_restricted);
            emptyView.setVisibility(View.VISIBLE);
            updateVisibilityOfRemoveMenu();
        } else if (!mIsUiRestricted && previouslyRestricted) {
            // Unlock it.
            emptyView.setVisibility(View.GONE);
            updateVisibilityOfRemoveMenu();
        }
    }

    @Override
    public void onViewStateRestored(Bundle savedInstanceState) {
        super.onViewStateRestored(savedInstanceState);
@@ -217,20 +243,18 @@ public class LocaleListEditor extends SettingsPreferenceFragment
        updateVisibilityOfRemoveMenu();
    }

    private static List<LocaleStore.LocaleInfo> getUserLocaleList(Context context) {
    private List<LocaleStore.LocaleInfo> getUserLocaleList() {
        final List<LocaleStore.LocaleInfo> result = new ArrayList<>();

        final LocaleList localeList = LocalePicker.getLocales();
        for (int i = 0; i < localeList.size(); i++) {
            Locale locale = localeList.get(i);
            result.add(LocaleStore.getLocaleInfo(locale));
        }

        return result;
    }

    private void configureDragAndDrop(View view) {
        final RecyclerView list = (RecyclerView) view.findViewById(R.id.dragList);
        final RecyclerView list = view.findViewById(R.id.dragList);
        final LocaleLinearLayoutManager llm = new LocaleLinearLayoutManager(getContext(), mAdapter);
        llm.setAutoMeasureEnabled(true);
        list.setLayoutManager(llm);
@@ -272,7 +296,8 @@ public class LocaleListEditor extends SettingsPreferenceFragment
        if (menuItemRemove != null) {
            menuItemRemove.setShowAsAction(
                    mRemoveMode ? MenuItem.SHOW_AS_ACTION_ALWAYS : MenuItem.SHOW_AS_ACTION_NEVER);
            menuItemRemove.setVisible(mAdapter.getItemCount() > 1);
            final boolean hasMultipleLanguages = mAdapter.getItemCount() > 1;
            menuItemRemove.setVisible(hasMultipleLanguages && !mIsUiRestricted);
        }
    }
}
+66 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2017 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.localepicker;

import android.content.Context;
import android.view.View;
import android.widget.TextView;
import com.android.settings.TestConfig;
import com.android.settings.testutils.SettingsRobolectricTestRunner;
import com.android.settings.testutils.shadow.ShadowSettingsPreferenceFragment;

import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
import org.robolectric.util.ReflectionHelpers;

@RunWith(SettingsRobolectricTestRunner.class)
@Config(manifest = TestConfig.MANIFEST_PATH,
        sdk = TestConfig.SDK_VERSION,
        shadows = { ShadowSettingsPreferenceFragment.class })
public class LocaleListEditorTest {

    private LocaleListEditor mLocaleListEditor;

    @Before
    public void setUp() {
        mLocaleListEditor = new LocaleListEditor();
        ReflectionHelpers.setField(mLocaleListEditor, "mEmptyTextView",
                new TextView(RuntimeEnvironment.application));
        ReflectionHelpers.setField(mLocaleListEditor, "mRestrictionsManager",
                RuntimeEnvironment.application.getSystemService(Context.RESTRICTIONS_SERVICE));
        ReflectionHelpers.setField(mLocaleListEditor, "mUserManager",
                RuntimeEnvironment.application.getSystemService(Context.USER_SERVICE));
    }

    @Test
    public void testDisallowConfigLocale_unrestrict() {
        ReflectionHelpers.setField(mLocaleListEditor, "mIsUiRestricted", true);
        mLocaleListEditor.onResume();
        Assert.assertEquals(View.GONE, mLocaleListEditor.getEmptyTextView().getVisibility());
    }

    @Test
    public void testDisallowConfigLocale_restrict() {
        ReflectionHelpers.setField(mLocaleListEditor, "mIsUiRestricted", false);
        mLocaleListEditor.onResume();
        Assert.assertEquals(View.VISIBLE, mLocaleListEditor.getEmptyTextView().getVisibility());
    }
}
+38 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2017 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.testutils.shadow;

import android.os.Bundle;

import com.android.settings.SettingsPreferenceFragment;
import org.robolectric.annotation.Implementation;
import org.robolectric.annotation.Implements;

/**
 * Shadow of {@link SettingsPreferenceFragment}.
 *
 * Override the {@link #onCreate(Bundle)} to skip a null pointer exception in
 * {@link android.content.res.Resources.Theme}, much the same as {@link ShadowDashboardFragment}.
 */
@Implements(SettingsPreferenceFragment.class)
public class ShadowSettingsPreferenceFragment {

    @Implementation
    public void onCreate(Bundle savedInstanceState) {
        // do nothing
    }
}
 No newline at end of file