Merge "Require work profile to be unlocked for changing notification settings in a different way" into pi-dev
am: a6d36c4e2e
Change-Id: I8b55406992369ecec72172d0a2620e6b42093d16
This commit is contained in:
@@ -16,10 +16,16 @@
|
|||||||
|
|
||||||
package com.android.settings;
|
package com.android.settings;
|
||||||
|
|
||||||
|
import android.app.ActivityManager;
|
||||||
import android.app.AlertDialog;
|
import android.app.AlertDialog;
|
||||||
|
import android.app.KeyguardManager;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.DialogInterface;
|
import android.content.DialogInterface;
|
||||||
|
import android.content.Intent;
|
||||||
import android.os.Bundle;
|
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.v14.preference.ListPreferenceDialogFragment;
|
||||||
import android.support.v7.preference.PreferenceViewHolder;
|
import android.support.v7.preference.PreferenceViewHolder;
|
||||||
import android.util.AttributeSet;
|
import android.util.AttributeSet;
|
||||||
@@ -32,6 +38,7 @@ import android.widget.ImageView;
|
|||||||
import android.widget.ListAdapter;
|
import android.widget.ListAdapter;
|
||||||
import android.widget.ListView;
|
import android.widget.ListView;
|
||||||
|
|
||||||
|
import com.android.settings.Utils;
|
||||||
import com.android.settingslib.RestrictedLockUtils;
|
import com.android.settingslib.RestrictedLockUtils;
|
||||||
import com.android.settingslib.RestrictedPreferenceHelper;
|
import com.android.settingslib.RestrictedPreferenceHelper;
|
||||||
|
|
||||||
@@ -43,6 +50,8 @@ import static com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
|
|||||||
public class RestrictedListPreference extends CustomListPreference {
|
public class RestrictedListPreference extends CustomListPreference {
|
||||||
private final RestrictedPreferenceHelper mHelper;
|
private final RestrictedPreferenceHelper mHelper;
|
||||||
private final List<RestrictedItem> mRestrictedItems = new ArrayList<>();
|
private final List<RestrictedItem> mRestrictedItems = new ArrayList<>();
|
||||||
|
private boolean mRequiresActiveUnlockedProfile = false;
|
||||||
|
private int mProfileUserId;
|
||||||
|
|
||||||
public RestrictedListPreference(Context context, AttributeSet attrs) {
|
public RestrictedListPreference(Context context, AttributeSet attrs) {
|
||||||
super(context, attrs);
|
super(context, attrs);
|
||||||
@@ -68,6 +77,24 @@ public class RestrictedListPreference extends CustomListPreference {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void performClick() {
|
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()) {
|
if (!mHelper.performClick()) {
|
||||||
super.performClick();
|
super.performClick();
|
||||||
}
|
}
|
||||||
@@ -92,6 +119,14 @@ public class RestrictedListPreference extends CustomListPreference {
|
|||||||
return mHelper.isDisabledByAdmin();
|
return mHelper.isDisabledByAdmin();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setRequiresActiveUnlockedProfile(boolean reqState) {
|
||||||
|
mRequiresActiveUnlockedProfile = reqState;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setProfileUserId(int profileUserId) {
|
||||||
|
mProfileUserId = profileUserId;
|
||||||
|
}
|
||||||
|
|
||||||
public boolean isRestrictedForEntry(CharSequence entry) {
|
public boolean isRestrictedForEntry(CharSequence entry) {
|
||||||
if (entry == null) {
|
if (entry == null) {
|
||||||
return false;
|
return false;
|
||||||
|
@@ -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_SECURE_NOTIFICATIONS;
|
||||||
import static android.app.admin.DevicePolicyManager.KEYGUARD_DISABLE_UNREDACTED_NOTIFICATIONS;
|
import static android.app.admin.DevicePolicyManager.KEYGUARD_DISABLE_UNREDACTED_NOTIFICATIONS;
|
||||||
|
|
||||||
import android.app.ActivityManager;
|
|
||||||
import android.app.admin.DevicePolicyManager;
|
import android.app.admin.DevicePolicyManager;
|
||||||
import android.app.KeyguardManager;
|
|
||||||
import android.content.ContentResolver;
|
import android.content.ContentResolver;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
|
||||||
import android.database.ContentObserver;
|
import android.database.ContentObserver;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.os.RemoteException;
|
|
||||||
import android.os.UserHandle;
|
import android.os.UserHandle;
|
||||||
import android.os.UserManager;
|
import android.os.UserManager;
|
||||||
import android.provider.Settings;
|
import android.provider.Settings;
|
||||||
@@ -101,6 +97,8 @@ public class LockScreenNotificationPreferenceController extends AbstractPreferen
|
|||||||
}
|
}
|
||||||
if (mProfileUserId != UserHandle.USER_NULL) {
|
if (mProfileUserId != UserHandle.USER_NULL) {
|
||||||
mLockscreenProfile = (RestrictedListPreference) screen.findPreference(mWorkSettingKey);
|
mLockscreenProfile = (RestrictedListPreference) screen.findPreference(mWorkSettingKey);
|
||||||
|
mLockscreenProfile.setRequiresActiveUnlockedProfile(true);
|
||||||
|
mLockscreenProfile.setProfileUserId(mProfileUserId);
|
||||||
} else {
|
} else {
|
||||||
setVisible(screen, mWorkSettingKey, false /* visible */);
|
setVisible(screen, mWorkSettingKey, false /* visible */);
|
||||||
setVisible(screen, mWorkSettingCategoryKey, false /* visible */);
|
setVisible(screen, mWorkSettingCategoryKey, false /* visible */);
|
||||||
@@ -244,39 +242,6 @@ public class LockScreenNotificationPreferenceController extends AbstractPreferen
|
|||||||
return false;
|
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,
|
private void setRestrictedIfNotificationFeaturesDisabled(CharSequence entry,
|
||||||
CharSequence entryValue, int keyguardNotificationFeatures) {
|
CharSequence entryValue, int keyguardNotificationFeatures) {
|
||||||
RestrictedLockUtils.EnforcedAdmin admin =
|
RestrictedLockUtils.EnforcedAdmin admin =
|
||||||
|
@@ -0,0 +1,124 @@
|
|||||||
|
/*
|
||||||
|
* 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();
|
||||||
|
}
|
||||||
|
}
|
@@ -44,6 +44,7 @@ public class ShadowUserManager extends org.robolectric.shadows.ShadowUserManager
|
|||||||
private final Map<String, List<EnforcingUser>> mRestrictionSources = new HashMap<>();
|
private final Map<String, List<EnforcingUser>> mRestrictionSources = new HashMap<>();
|
||||||
private final List<UserInfo> mUserProfileInfos = new ArrayList<>();
|
private final List<UserInfo> mUserProfileInfos = new ArrayList<>();
|
||||||
private final Set<Integer> mManagedProfiles = new HashSet<>();
|
private final Set<Integer> mManagedProfiles = new HashSet<>();
|
||||||
|
private boolean mIsQuietModeEnabled = false;
|
||||||
|
|
||||||
@Resetter
|
@Resetter
|
||||||
public void reset() {
|
public void reset() {
|
||||||
@@ -52,6 +53,7 @@ public class ShadowUserManager extends org.robolectric.shadows.ShadowUserManager
|
|||||||
mUserProfileInfos.clear();
|
mUserProfileInfos.clear();
|
||||||
mRestrictionSources.clear();
|
mRestrictionSources.clear();
|
||||||
mManagedProfiles.clear();
|
mManagedProfiles.clear();
|
||||||
|
mIsQuietModeEnabled = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setUserInfo(int userHandle, UserInfo userInfo) {
|
public void setUserInfo(int userHandle, UserInfo userInfo) {
|
||||||
@@ -110,4 +112,13 @@ public class ShadowUserManager extends org.robolectric.shadows.ShadowUserManager
|
|||||||
public void addManagedProfile(int userId) {
|
public void addManagedProfile(int userId) {
|
||||||
mManagedProfiles.add(userId);
|
mManagedProfiles.add(userId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Implementation
|
||||||
|
public boolean isQuietModeEnabled(UserHandle userHandle) {
|
||||||
|
return mIsQuietModeEnabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setQuietModeEnabled(boolean enabled) {
|
||||||
|
mIsQuietModeEnabled = enabled;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user