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

Commit b7c83db4 authored by Eran Messeri's avatar Eran Messeri Committed by android-build-merger
Browse files

Merge "Require work profile to be unlocked for changing notification settings...

Merge "Require work profile to be unlocked for changing notification settings in a different way" into pi-dev
am: a6d36c4e

Change-Id: I8b55406992369ecec72172d0a2620e6b42093d16
parents fb5b43d7 a6d36c4e
Loading
Loading
Loading
Loading
+36 −1
Original line number Diff line number Diff line
@@ -16,10 +16,16 @@

package com.android.settings;

import android.app.ActivityManager;
import android.app.AlertDialog;
import android.app.KeyguardManager;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.os.RemoteException;
import android.os.UserManager;
import android.support.annotation.VisibleForTesting;
import android.support.v14.preference.ListPreferenceDialogFragment;
import android.support.v7.preference.PreferenceViewHolder;
import android.util.AttributeSet;
@@ -32,6 +38,7 @@ import android.widget.ImageView;
import android.widget.ListAdapter;
import android.widget.ListView;

import com.android.settings.Utils;
import com.android.settingslib.RestrictedLockUtils;
import com.android.settingslib.RestrictedPreferenceHelper;

@@ -43,6 +50,8 @@ import static com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
public class RestrictedListPreference extends CustomListPreference {
    private final RestrictedPreferenceHelper mHelper;
    private final List<RestrictedItem> mRestrictedItems = new ArrayList<>();
    private boolean mRequiresActiveUnlockedProfile = false;
    private int mProfileUserId;

    public RestrictedListPreference(Context context, AttributeSet attrs) {
        super(context, attrs);
@@ -68,6 +77,24 @@ public class RestrictedListPreference extends CustomListPreference {

    @Override
    public void performClick() {
        if (mRequiresActiveUnlockedProfile) {
            // Check if the profile is started, first.
            if (Utils.startQuietModeDialogIfNecessary(getContext(), UserManager.get(getContext()),
                    mProfileUserId)) {
                return;
            }

            // Next, check if the profile is unlocked.
            KeyguardManager manager =
                    (KeyguardManager) getContext().getSystemService(Context.KEYGUARD_SERVICE);
            if (manager.isDeviceLocked(mProfileUserId)) {
                Intent intent = manager.createConfirmDeviceCredentialIntent(
                        null, null, mProfileUserId);
                getContext().startActivity(intent);
                return;
            }
        }

        if (!mHelper.performClick()) {
            super.performClick();
        }
@@ -92,6 +119,14 @@ public class RestrictedListPreference extends CustomListPreference {
        return mHelper.isDisabledByAdmin();
    }

    public void setRequiresActiveUnlockedProfile(boolean reqState) {
        mRequiresActiveUnlockedProfile = reqState;
    }

    public void setProfileUserId(int profileUserId) {
        mProfileUserId = profileUserId;
    }

    public boolean isRestrictedForEntry(CharSequence entry) {
        if (entry == null) {
            return false;
+2 −37
Original line number Diff line number Diff line
@@ -19,16 +19,12 @@ package com.android.settings.notification;
import static android.app.admin.DevicePolicyManager.KEYGUARD_DISABLE_SECURE_NOTIFICATIONS;
import static android.app.admin.DevicePolicyManager.KEYGUARD_DISABLE_UNREDACTED_NOTIFICATIONS;

import android.app.ActivityManager;
import android.app.admin.DevicePolicyManager;
import android.app.KeyguardManager;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.database.ContentObserver;
import android.net.Uri;
import android.os.Handler;
import android.os.RemoteException;
import android.os.UserHandle;
import android.os.UserManager;
import android.provider.Settings;
@@ -101,6 +97,8 @@ public class LockScreenNotificationPreferenceController extends AbstractPreferen
        }
        if (mProfileUserId != UserHandle.USER_NULL) {
            mLockscreenProfile = (RestrictedListPreference) screen.findPreference(mWorkSettingKey);
            mLockscreenProfile.setRequiresActiveUnlockedProfile(true);
            mLockscreenProfile.setProfileUserId(mProfileUserId);
        } else {
            setVisible(screen, mWorkSettingKey, false /* visible */);
            setVisible(screen, mWorkSettingCategoryKey, false /* visible */);
@@ -244,39 +242,6 @@ public class LockScreenNotificationPreferenceController extends AbstractPreferen
        return false;
    }

    @Override
    public boolean handlePreferenceTreeClick(Preference preference) {
        final String key = preference.getKey();
        if (!TextUtils.equals(mWorkSettingKey, key)) {
            return false;
        }

        // Check if the profile is started, first.
        if (Utils.startQuietModeDialogIfNecessary(mContext, UserManager.get(mContext),
                    mProfileUserId)) {
            return true;
        }

        // Next, check if the profile is unlocked.
        KeyguardManager manager =
                (KeyguardManager) mContext.getSystemService(Context.KEYGUARD_SERVICE);
        if (manager.isDeviceLocked(mProfileUserId)) {
            //TODO: Figure out how to return the user to the current activity so they
            //don't have to navigate to the settings again.
            Intent intent = manager.createConfirmDeviceCredentialIntent(
                    null, null, mProfileUserId);
            try {
                ActivityManager.getService().startConfirmDeviceCredentialIntent(intent,
                        null /*options*/);
            } catch (RemoteException ignored) {
            }

            return true;
        }

        return false;
    }

    private void setRestrictedIfNotificationFeaturesDisabled(CharSequence entry,
            CharSequence entryValue, int keyguardNotificationFeatures) {
        RestrictedLockUtils.EnforcedAdmin admin =
+124 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2018 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;

import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import static org.robolectric.RuntimeEnvironment.application;
import static org.robolectric.Shadows.shadowOf;

import android.app.KeyguardManager;
import android.content.Intent;
import android.os.Bundle;
import android.util.AttributeSet;
import com.android.settings.testutils.SettingsRobolectricTestRunner;
import com.android.settings.testutils.shadow.ShadowUserManager;
import com.android.settingslib.RestrictedPreferenceHelper;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.Shadows;
import org.robolectric.annotation.Config;
import org.robolectric.shadows.ShadowKeyguardManager;
import org.robolectric.util.ReflectionHelpers;

@RunWith(SettingsRobolectricTestRunner.class)
@Config(
        shadows = {
            ShadowUserManager.class,
            ShadowKeyguardManager.class,
        })
public class RestrictedListPreferenceTest {
    private static final int PROFILE_USER_ID = 11;
    // From UnlaunchableAppActivity
    private static final int UNLAUNCHABLE_REASON_QUIET_MODE = 1;
    private static final String EXTRA_UNLAUNCHABLE_REASON = "unlaunchable_reason";

    private ShadowUserManager mShadowUserManager;
    private ShadowKeyguardManager mShadowKeyguardManager;
    private RestrictedListPreference mPreference;
    private RestrictedPreferenceHelper mMockHelper;

    @Before
    public void setUp() {
        mShadowKeyguardManager =
                Shadows.shadowOf(application.getSystemService(KeyguardManager.class));
        mMockHelper = mock(RestrictedPreferenceHelper.class);
        mShadowUserManager = ShadowUserManager.getShadow();
        mPreference = new RestrictedListPreference(application, mock(AttributeSet.class));
        mPreference.setProfileUserId(PROFILE_USER_ID);
        ReflectionHelpers.setField(mPreference, "mHelper", mMockHelper);
    }

    @Test
    public void performClick_profileLocked() {
        mPreference.setRequiresActiveUnlockedProfile(true);
        mShadowUserManager.setQuietModeEnabled(false);
        mShadowKeyguardManager.setIsDeviceLocked(PROFILE_USER_ID, true);
        // Device has to be marked as secure so the real KeyguardManager will create a non-null
        // intent.
        mShadowKeyguardManager.setIsDeviceSecure(PROFILE_USER_ID, true);
        mPreference.performClick();
        // Make sure that the performClick method on the helper is never reached.
        verify(mMockHelper, never()).performClick();
        // Assert that a CONFIRM_DEVICE_CREDENTIAL intent has been started.
        Intent started = shadowOf(application).getNextStartedActivity();
        assertThat(started.getExtras().getInt(Intent.EXTRA_USER_ID)).isEqualTo(PROFILE_USER_ID);
        assertThat(started.getAction())
                .isEqualTo(KeyguardManager.ACTION_CONFIRM_DEVICE_CREDENTIAL_WITH_USER);
    }

    @Test
    public void performClick_profileDisabled() {
        mPreference.setRequiresActiveUnlockedProfile(true);
        mShadowUserManager.setQuietModeEnabled(true);
        mShadowKeyguardManager.setIsDeviceLocked(PROFILE_USER_ID, false);
        mPreference.performClick();
        // Make sure that the performClick method on the helper is never reached.
        verify(mMockHelper, never()).performClick();
        // Assert that a new intent for enabling the work profile is started.
        Intent started = shadowOf(application).getNextStartedActivity();
        Bundle extras = started.getExtras();
        int reason = extras.getInt(EXTRA_UNLAUNCHABLE_REASON);
        assertThat(reason).isEqualTo(UNLAUNCHABLE_REASON_QUIET_MODE);
    }

    @Test
    public void performClick_profileAvailable() {
        // Verify that the helper's perfomClick method is called if the profile is
        // available and unlocked.
        mPreference.setRequiresActiveUnlockedProfile(true);
        mShadowUserManager.setQuietModeEnabled(false);
        mShadowKeyguardManager.setIsDeviceLocked(PROFILE_USER_ID, false);
        when(mMockHelper.performClick()).thenReturn(true);
        mPreference.performClick();
        verify(mMockHelper).performClick();
    }

    @Test
    public void performClick_profileLockedAndUnlockedProfileNotRequired() {
        // Verify that even if the profile is disabled, if the Preference class does not
        // require it than the regular flow takes place.
        mPreference.setRequiresActiveUnlockedProfile(false);
        mShadowUserManager.setQuietModeEnabled(true);
        when(mMockHelper.performClick()).thenReturn(true);
        mPreference.performClick();
        verify(mMockHelper).performClick();
    }
}
+11 −0
Original line number Diff line number Diff line
@@ -44,6 +44,7 @@ public class ShadowUserManager extends org.robolectric.shadows.ShadowUserManager
    private final Map<String, List<EnforcingUser>> mRestrictionSources = new HashMap<>();
    private final List<UserInfo> mUserProfileInfos = new ArrayList<>();
    private final Set<Integer> mManagedProfiles = new HashSet<>();
    private boolean mIsQuietModeEnabled = false;

    @Resetter
    public void reset() {
@@ -52,6 +53,7 @@ public class ShadowUserManager extends org.robolectric.shadows.ShadowUserManager
        mUserProfileInfos.clear();
        mRestrictionSources.clear();
        mManagedProfiles.clear();
        mIsQuietModeEnabled = false;
    }

    public void setUserInfo(int userHandle, UserInfo userInfo) {
@@ -110,4 +112,13 @@ public class ShadowUserManager extends org.robolectric.shadows.ShadowUserManager
    public void addManagedProfile(int userId) {
        mManagedProfiles.add(userId);
    }

    @Implementation
    public boolean isQuietModeEnabled(UserHandle userHandle) {
        return mIsQuietModeEnabled;
    }

    public void setQuietModeEnabled(boolean enabled) {
        mIsQuietModeEnabled = enabled;
    }
}