Loading res/values/strings.xml +4 −0 Original line number Diff line number Diff line Loading @@ -2832,6 +2832,10 @@ <string name="adaptive_sleep_summary_on">On / Screen won\u2019t turn off if you\u2019re looking at it</string> <!-- Setting option summary when adaptive sleep is off [CHAR LIMIT=NONE] --> <string name="adaptive_sleep_summary_off">Off</string> <!-- adaptive_sleep settings screen, title about the required permission is missing [CHAR LIMIT=NONE]--> <string name="adaptive_sleep_title_no_permission">Camera access needed</string> <!-- adaptive_sleep settings screen, subtitle when permission is missing [CHAR LIMIT=NONE]--> <string name="adaptive_sleep_summary_no_permission">Tap to manage permissions for Device Personalization Services</string> <!-- Description about the feature adaptive sleep [CHAR LIMIT=NONE]--> <string name="adaptive_sleep_description">Prevents your screen from turning off if you\u2019re looking at it</string> <!-- Description feature's privacy sensitive details to make sure users understand what feature users, what it saves/sends etc [CHAR LIMIT=NONE]--> Loading src/com/android/settings/display/AdaptiveSleepDetailPreferenceController.java +6 −2 Original line number Diff line number Diff line Loading @@ -21,8 +21,11 @@ import android.content.Context; import androidx.preference.Preference; public class AdaptiveSleepDetailPreferenceController extends AdaptiveSleepPreferenceController { private final Context mContext; public AdaptiveSleepDetailPreferenceController(Context context, String key) { super(context, key); mContext = context; } @Override Loading @@ -42,6 +45,7 @@ public class AdaptiveSleepDetailPreferenceController extends AdaptiveSleepPrefer @Override public void updateState(Preference preference) { super.updateState(preference); preference.setEnabled(super.hasSufficientPermissions); preference.setEnabled(AdaptiveSleepPreferenceController.hasSufficientPermission( mContext.getPackageManager())); } } No newline at end of file src/com/android/settings/display/AdaptiveSleepPreferenceController.java +2 −2 Original line number Diff line number Diff line Loading @@ -29,7 +29,7 @@ public class AdaptiveSleepPreferenceController extends TogglePreferenceControlle private static final String SYSTEM_KEY = ADAPTIVE_SLEEP; private static final int DEFAULT_VALUE = 0; final boolean hasSufficientPermissions; private final boolean hasSufficientPermissions; public AdaptiveSleepPreferenceController(Context context, String key) { super(context, key); Loading Loading @@ -71,7 +71,7 @@ public class AdaptiveSleepPreferenceController extends TogglePreferenceControlle : UNSUPPORTED_ON_DEVICE; } private static boolean hasSufficientPermission(PackageManager packageManager) { static boolean hasSufficientPermission(PackageManager packageManager) { final String attentionPackage = packageManager.getAttentionServicePackageName(); return attentionPackage != null && packageManager.checkPermission( Manifest.permission.CAMERA, attentionPackage) == PackageManager.PERMISSION_GRANTED; Loading src/com/android/settings/display/AdaptiveSleepSettings.java +56 −4 Original line number Diff line number Diff line Loading @@ -16,16 +16,21 @@ package com.android.settings.display; import static com.android.settings.display.AdaptiveSleepPreferenceController.hasSufficientPermission; import static com.android.settings.homepage.contextualcards.slices.ContextualAdaptiveSleepSlice.PREF; import static com.android.settings.homepage.contextualcards.slices.ContextualAdaptiveSleepSlice.PREF_KEY_INTERACTED; import android.app.settings.SettingsEnums; import android.content.Context; import android.content.SharedPreferences; import android.content.Intent; import android.content.pm.PackageManager; import android.net.Uri; import android.os.Bundle; import android.provider.SearchIndexableResource; import android.util.Log; import androidx.preference.Preference; import com.android.internal.annotations.VisibleForTesting; import com.android.settings.R; import com.android.settings.dashboard.DashboardFragment; import com.android.settings.search.BaseSearchIndexProvider; Loading @@ -39,23 +44,45 @@ import java.util.List; public class AdaptiveSleepSettings extends DashboardFragment { private static final String TAG = "AdaptiveSleepSettings"; private Context mContext; private String mPackageName; private PackageManager mPackageManager; @VisibleForTesting Preference mPermissionRequiredPreference; @Override public void onCreate(Bundle icicle) { super.onCreate(icicle); final FooterPreference footerPreference = mFooterPreferenceMixin.createFooterPreference(); final Context context = getContext(); mContext = getContext(); mPermissionRequiredPreference = createPermissionMissionPreference(); footerPreference.setIcon(R.drawable.ic_privacy_shield_24dp); footerPreference.setTitle(R.string.adaptive_sleep_privacy); context.getSharedPreferences(PREF, Context.MODE_PRIVATE) getPreferenceScreen().addPreference(mPermissionRequiredPreference); mPermissionRequiredPreference.setVisible(false); mPackageManager = mContext.getPackageManager(); mPackageName = mPackageManager.getAttentionServicePackageName(); mContext.getSharedPreferences(PREF, Context.MODE_PRIVATE) .edit() .putBoolean(PREF_KEY_INTERACTED, true) .apply(); } @Override public void onResume() { super.onResume(); if (!hasSufficientPermission(mPackageManager)) { mPermissionRequiredPreference.setVisible(true); } else { mPermissionRequiredPreference.setVisible(false); } } @Override protected int getPreferenceScreenResId() { return R.xml.adaptive_sleep_detail; Loading Loading @@ -86,4 +113,29 @@ public class AdaptiveSleepSettings extends DashboardFragment { return Arrays.asList(sir); } }; private Preference createPermissionMissionPreference() { Preference preference = new Preference(mContext, null); preference.setIcon(R.drawable.ic_info_outline_24); // Makes sure it's above the toggle. preference.setOrder(1); preference.setPersistent(true); preference.setTitle(R.string.adaptive_sleep_title_no_permission); preference.setSummary(R.string.adaptive_sleep_summary_no_permission); preference.setOnPreferenceClickListener(p -> { final Intent intent = new Intent( android.provider.Settings.ACTION_APPLICATION_DETAILS_SETTINGS); intent.setData(Uri.parse("package:" + mPackageName)); mContext.startActivity(intent); return true; }); return preference; } @VisibleForTesting void setupForTesting(PackageManager packageManager, Context context) { mContext = context; mPackageManager = packageManager; mPermissionRequiredPreference = createPermissionMissionPreference(); } } tests/robotests/src/com/android/settings/display/AdaptiveSleepSettingsTest.java 0 → 100644 +80 −0 Original line number Diff line number Diff line /* * Copyright (C) 2019 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.display; import static com.google.common.truth.Truth.assertThat; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.spy; import android.Manifest; import android.content.Context; import android.content.pm.PackageManager; import androidx.preference.PreferenceScreen; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.robolectric.RobolectricTestRunner; import org.robolectric.RuntimeEnvironment; @RunWith(RobolectricTestRunner.class) public class AdaptiveSleepSettingsTest { private AdaptiveSleepSettings mSettings; private static final String PACKAGE_NAME = "package_name"; @Mock private PackageManager mPackageManager; @Mock private PreferenceScreen mScreen; @Before public void setUp() { MockitoAnnotations.initMocks(this); Context context = RuntimeEnvironment.application; mSettings = spy(new AdaptiveSleepSettings()); doReturn(PACKAGE_NAME).when(mPackageManager).getAttentionServicePackageName(); doReturn(PackageManager.PERMISSION_GRANTED).when(mPackageManager).checkPermission( Manifest.permission.CAMERA, PACKAGE_NAME); doReturn(mScreen).when(mSettings).getPreferenceScreen(); mSettings.setupForTesting(mPackageManager, context); mSettings.onAttach(context); } @Test public void onResume_hasPermission_preferenceInvisible() { mSettings.onResume(); assertThat(mSettings.mPermissionRequiredPreference.isVisible()).isFalse(); } @Test public void onResume_noPermission_preferenceVisible() { doReturn(PackageManager.PERMISSION_DENIED).when(mPackageManager).checkPermission( Manifest.permission.CAMERA, PACKAGE_NAME); mSettings.onResume(); assertThat(mSettings.mPermissionRequiredPreference.isVisible()).isTrue(); } } Loading
res/values/strings.xml +4 −0 Original line number Diff line number Diff line Loading @@ -2832,6 +2832,10 @@ <string name="adaptive_sleep_summary_on">On / Screen won\u2019t turn off if you\u2019re looking at it</string> <!-- Setting option summary when adaptive sleep is off [CHAR LIMIT=NONE] --> <string name="adaptive_sleep_summary_off">Off</string> <!-- adaptive_sleep settings screen, title about the required permission is missing [CHAR LIMIT=NONE]--> <string name="adaptive_sleep_title_no_permission">Camera access needed</string> <!-- adaptive_sleep settings screen, subtitle when permission is missing [CHAR LIMIT=NONE]--> <string name="adaptive_sleep_summary_no_permission">Tap to manage permissions for Device Personalization Services</string> <!-- Description about the feature adaptive sleep [CHAR LIMIT=NONE]--> <string name="adaptive_sleep_description">Prevents your screen from turning off if you\u2019re looking at it</string> <!-- Description feature's privacy sensitive details to make sure users understand what feature users, what it saves/sends etc [CHAR LIMIT=NONE]--> Loading
src/com/android/settings/display/AdaptiveSleepDetailPreferenceController.java +6 −2 Original line number Diff line number Diff line Loading @@ -21,8 +21,11 @@ import android.content.Context; import androidx.preference.Preference; public class AdaptiveSleepDetailPreferenceController extends AdaptiveSleepPreferenceController { private final Context mContext; public AdaptiveSleepDetailPreferenceController(Context context, String key) { super(context, key); mContext = context; } @Override Loading @@ -42,6 +45,7 @@ public class AdaptiveSleepDetailPreferenceController extends AdaptiveSleepPrefer @Override public void updateState(Preference preference) { super.updateState(preference); preference.setEnabled(super.hasSufficientPermissions); preference.setEnabled(AdaptiveSleepPreferenceController.hasSufficientPermission( mContext.getPackageManager())); } } No newline at end of file
src/com/android/settings/display/AdaptiveSleepPreferenceController.java +2 −2 Original line number Diff line number Diff line Loading @@ -29,7 +29,7 @@ public class AdaptiveSleepPreferenceController extends TogglePreferenceControlle private static final String SYSTEM_KEY = ADAPTIVE_SLEEP; private static final int DEFAULT_VALUE = 0; final boolean hasSufficientPermissions; private final boolean hasSufficientPermissions; public AdaptiveSleepPreferenceController(Context context, String key) { super(context, key); Loading Loading @@ -71,7 +71,7 @@ public class AdaptiveSleepPreferenceController extends TogglePreferenceControlle : UNSUPPORTED_ON_DEVICE; } private static boolean hasSufficientPermission(PackageManager packageManager) { static boolean hasSufficientPermission(PackageManager packageManager) { final String attentionPackage = packageManager.getAttentionServicePackageName(); return attentionPackage != null && packageManager.checkPermission( Manifest.permission.CAMERA, attentionPackage) == PackageManager.PERMISSION_GRANTED; Loading
src/com/android/settings/display/AdaptiveSleepSettings.java +56 −4 Original line number Diff line number Diff line Loading @@ -16,16 +16,21 @@ package com.android.settings.display; import static com.android.settings.display.AdaptiveSleepPreferenceController.hasSufficientPermission; import static com.android.settings.homepage.contextualcards.slices.ContextualAdaptiveSleepSlice.PREF; import static com.android.settings.homepage.contextualcards.slices.ContextualAdaptiveSleepSlice.PREF_KEY_INTERACTED; import android.app.settings.SettingsEnums; import android.content.Context; import android.content.SharedPreferences; import android.content.Intent; import android.content.pm.PackageManager; import android.net.Uri; import android.os.Bundle; import android.provider.SearchIndexableResource; import android.util.Log; import androidx.preference.Preference; import com.android.internal.annotations.VisibleForTesting; import com.android.settings.R; import com.android.settings.dashboard.DashboardFragment; import com.android.settings.search.BaseSearchIndexProvider; Loading @@ -39,23 +44,45 @@ import java.util.List; public class AdaptiveSleepSettings extends DashboardFragment { private static final String TAG = "AdaptiveSleepSettings"; private Context mContext; private String mPackageName; private PackageManager mPackageManager; @VisibleForTesting Preference mPermissionRequiredPreference; @Override public void onCreate(Bundle icicle) { super.onCreate(icicle); final FooterPreference footerPreference = mFooterPreferenceMixin.createFooterPreference(); final Context context = getContext(); mContext = getContext(); mPermissionRequiredPreference = createPermissionMissionPreference(); footerPreference.setIcon(R.drawable.ic_privacy_shield_24dp); footerPreference.setTitle(R.string.adaptive_sleep_privacy); context.getSharedPreferences(PREF, Context.MODE_PRIVATE) getPreferenceScreen().addPreference(mPermissionRequiredPreference); mPermissionRequiredPreference.setVisible(false); mPackageManager = mContext.getPackageManager(); mPackageName = mPackageManager.getAttentionServicePackageName(); mContext.getSharedPreferences(PREF, Context.MODE_PRIVATE) .edit() .putBoolean(PREF_KEY_INTERACTED, true) .apply(); } @Override public void onResume() { super.onResume(); if (!hasSufficientPermission(mPackageManager)) { mPermissionRequiredPreference.setVisible(true); } else { mPermissionRequiredPreference.setVisible(false); } } @Override protected int getPreferenceScreenResId() { return R.xml.adaptive_sleep_detail; Loading Loading @@ -86,4 +113,29 @@ public class AdaptiveSleepSettings extends DashboardFragment { return Arrays.asList(sir); } }; private Preference createPermissionMissionPreference() { Preference preference = new Preference(mContext, null); preference.setIcon(R.drawable.ic_info_outline_24); // Makes sure it's above the toggle. preference.setOrder(1); preference.setPersistent(true); preference.setTitle(R.string.adaptive_sleep_title_no_permission); preference.setSummary(R.string.adaptive_sleep_summary_no_permission); preference.setOnPreferenceClickListener(p -> { final Intent intent = new Intent( android.provider.Settings.ACTION_APPLICATION_DETAILS_SETTINGS); intent.setData(Uri.parse("package:" + mPackageName)); mContext.startActivity(intent); return true; }); return preference; } @VisibleForTesting void setupForTesting(PackageManager packageManager, Context context) { mContext = context; mPackageManager = packageManager; mPermissionRequiredPreference = createPermissionMissionPreference(); } }
tests/robotests/src/com/android/settings/display/AdaptiveSleepSettingsTest.java 0 → 100644 +80 −0 Original line number Diff line number Diff line /* * Copyright (C) 2019 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.display; import static com.google.common.truth.Truth.assertThat; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.spy; import android.Manifest; import android.content.Context; import android.content.pm.PackageManager; import androidx.preference.PreferenceScreen; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.robolectric.RobolectricTestRunner; import org.robolectric.RuntimeEnvironment; @RunWith(RobolectricTestRunner.class) public class AdaptiveSleepSettingsTest { private AdaptiveSleepSettings mSettings; private static final String PACKAGE_NAME = "package_name"; @Mock private PackageManager mPackageManager; @Mock private PreferenceScreen mScreen; @Before public void setUp() { MockitoAnnotations.initMocks(this); Context context = RuntimeEnvironment.application; mSettings = spy(new AdaptiveSleepSettings()); doReturn(PACKAGE_NAME).when(mPackageManager).getAttentionServicePackageName(); doReturn(PackageManager.PERMISSION_GRANTED).when(mPackageManager).checkPermission( Manifest.permission.CAMERA, PACKAGE_NAME); doReturn(mScreen).when(mSettings).getPreferenceScreen(); mSettings.setupForTesting(mPackageManager, context); mSettings.onAttach(context); } @Test public void onResume_hasPermission_preferenceInvisible() { mSettings.onResume(); assertThat(mSettings.mPermissionRequiredPreference.isVisible()).isFalse(); } @Test public void onResume_noPermission_preferenceVisible() { doReturn(PackageManager.PERMISSION_DENIED).when(mPackageManager).checkPermission( Manifest.permission.CAMERA, PACKAGE_NAME); mSettings.onResume(); assertThat(mSettings.mPermissionRequiredPreference.isVisible()).isTrue(); } }