Loading res/xml/adaptive_sleep_detail.xml +8 −0 Original line number Diff line number Diff line Loading @@ -28,6 +28,14 @@ settings:preview="@drawable/adaptive_sleep" settings:controller="com.android.settings.widget.VideoPreferenceController"/> <Preference android:key="adaptive_sleep_permission" android:title="@string/adaptive_sleep_title_no_permission" android:summary="@string/adaptive_sleep_summary_no_permission" android:icon="@drawable/ic_info_outline_24" settings:controller="com.android.settings.display.AdaptiveSleepPermissionPreferenceController" /> <com.android.settingslib.RestrictedSwitchPreference android:key="adaptive_sleep" android:title="@string/adaptive_sleep_title" Loading src/com/android/settings/display/AdaptiveSleepDetailPreferenceController.java +1 −4 Original line number Diff line number Diff line Loading @@ -21,11 +21,9 @@ 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 @@ -45,7 +43,6 @@ public class AdaptiveSleepDetailPreferenceController extends AdaptiveSleepPrefer @Override public void updateState(Preference preference) { super.updateState(preference); preference.setEnabled(AdaptiveSleepPreferenceController.hasSufficientPermission( mContext.getPackageManager())); preference.setEnabled(hasSufficientPermission(mContext.getPackageManager())); } } No newline at end of file src/com/android/settings/display/AdaptiveSleepPermissionPreferenceController.java 0 → 100644 +63 −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.android.settings.display.AdaptiveSleepPreferenceController.hasSufficientPermission; import android.content.Context; import android.content.Intent; import android.net.Uri; import android.text.TextUtils; import androidx.preference.Preference; import com.android.settings.core.BasePreferenceController; public class AdaptiveSleepPermissionPreferenceController extends BasePreferenceController { final static String PREF_NAME = "adaptive_sleep_permission"; private final Intent mIntent; public AdaptiveSleepPermissionPreferenceController(Context context, String key) { super(context, key); final String packageName = context.getPackageManager().getAttentionServicePackageName(); mIntent = new Intent(android.provider.Settings.ACTION_APPLICATION_DETAILS_SETTINGS); mIntent.setData(Uri.parse("package:" + packageName)); } @Override @AvailabilityStatus public int getAvailabilityStatus() { return AVAILABLE_UNSEARCHABLE; } @Override public boolean handlePreferenceTreeClick(Preference preference) { if (TextUtils.equals(getPreferenceKey(), preference.getKey())) { mContext.startActivity(mIntent); return true; } return super.handlePreferenceTreeClick(preference); } @Override public void updateState(Preference preference) { super.updateState(preference); if (TextUtils.equals(getPreferenceKey(), preference.getKey())) { preference.setVisible(!hasSufficientPermission(mContext.getPackageManager())); } } } src/com/android/settings/display/AdaptiveSleepSettings.java +6 −51 Original line number Diff line number Diff line Loading @@ -16,21 +16,16 @@ 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.Intent; import android.content.pm.PackageManager; import android.net.Uri; import android.os.Bundle; import android.provider.SearchIndexableResource; 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 @@ -45,11 +40,6 @@ 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) { Loading @@ -57,32 +47,22 @@ public class AdaptiveSleepSettings extends DashboardFragment { final FooterPreference footerPreference = mFooterPreferenceMixin.createFooterPreference(); mContext = getContext(); mPermissionRequiredPreference = createPermissionMissionPreference(); footerPreference.setIcon(R.drawable.ic_privacy_shield_24dp); footerPreference.setTitle(R.string.adaptive_sleep_privacy); getPreferenceScreen().addPreference(mPermissionRequiredPreference); mPermissionRequiredPreference.setVisible(false); mPackageManager = mContext.getPackageManager(); mPackageName = mPackageManager.getAttentionServicePackageName(); Preference permissionPreference = findPreference( AdaptiveSleepPermissionPreferenceController.PREF_NAME); if (permissionPreference != null) { permissionPreference.setVisible(false); } 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 @@ -113,29 +93,4 @@ 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→tests/robotests/src/com/android/settings/display/AdaptiveSleepPermissionPreferenceControllerTest.java +23 −20 Original line number Diff line number Diff line Loading @@ -16,65 +16,68 @@ package com.android.settings.display; import static com.android.settings.core.BasePreferenceController.AVAILABLE_UNSEARCHABLE; import static com.google.common.truth.Truth.assertThat; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; import android.Manifest; import android.content.Context; import android.content.pm.PackageManager; import androidx.preference.PreferenceScreen; import androidx.preference.Preference; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.Mockito; 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"; public class AdaptiveSleepPermissionPreferenceControllerTest { private final static String PACKAGE_NAME = "package_name"; private AdaptiveSleepPermissionPreferenceController mController; @Mock private PackageManager mPackageManager; @Mock private PreferenceScreen mScreen; private Preference mPreference; @Before public void setUp() { MockitoAnnotations.initMocks(this); Context context = RuntimeEnvironment.application; mSettings = spy(new AdaptiveSleepSettings()); Context context = Mockito.spy(RuntimeEnvironment.application); doReturn(mPackageManager).when(context).getPackageManager(); 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); mController = new AdaptiveSleepPermissionPreferenceController(context, "test_key"); doReturn(mController.getPreferenceKey()).when(mPreference).getKey(); } @Test public void getAvailabilityStatus_returnAvailableUnsearchable() { assertThat(mController.getAvailabilityStatus()).isEqualTo(AVAILABLE_UNSEARCHABLE); } @Test public void onResume_hasPermission_preferenceInvisible() { mSettings.onResume(); public void updateStates_permissionGranted_preferenceInvisible() { mController.updateState(mPreference); assertThat(mSettings.mPermissionRequiredPreference.isVisible()).isFalse(); verify(mPreference).setVisible(false); } @Test public void onResume_noPermission_preferenceVisible() { public void updateStates_permissionRevoked_preferenceVisible() { doReturn(PackageManager.PERMISSION_DENIED).when(mPackageManager).checkPermission( Manifest.permission.CAMERA, PACKAGE_NAME); mSettings.onResume(); mController.updateState(mPreference); assertThat(mSettings.mPermissionRequiredPreference.isVisible()).isTrue(); verify(mPreference).setVisible(true); } } Loading
res/xml/adaptive_sleep_detail.xml +8 −0 Original line number Diff line number Diff line Loading @@ -28,6 +28,14 @@ settings:preview="@drawable/adaptive_sleep" settings:controller="com.android.settings.widget.VideoPreferenceController"/> <Preference android:key="adaptive_sleep_permission" android:title="@string/adaptive_sleep_title_no_permission" android:summary="@string/adaptive_sleep_summary_no_permission" android:icon="@drawable/ic_info_outline_24" settings:controller="com.android.settings.display.AdaptiveSleepPermissionPreferenceController" /> <com.android.settingslib.RestrictedSwitchPreference android:key="adaptive_sleep" android:title="@string/adaptive_sleep_title" Loading
src/com/android/settings/display/AdaptiveSleepDetailPreferenceController.java +1 −4 Original line number Diff line number Diff line Loading @@ -21,11 +21,9 @@ 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 @@ -45,7 +43,6 @@ public class AdaptiveSleepDetailPreferenceController extends AdaptiveSleepPrefer @Override public void updateState(Preference preference) { super.updateState(preference); preference.setEnabled(AdaptiveSleepPreferenceController.hasSufficientPermission( mContext.getPackageManager())); preference.setEnabled(hasSufficientPermission(mContext.getPackageManager())); } } No newline at end of file
src/com/android/settings/display/AdaptiveSleepPermissionPreferenceController.java 0 → 100644 +63 −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.android.settings.display.AdaptiveSleepPreferenceController.hasSufficientPermission; import android.content.Context; import android.content.Intent; import android.net.Uri; import android.text.TextUtils; import androidx.preference.Preference; import com.android.settings.core.BasePreferenceController; public class AdaptiveSleepPermissionPreferenceController extends BasePreferenceController { final static String PREF_NAME = "adaptive_sleep_permission"; private final Intent mIntent; public AdaptiveSleepPermissionPreferenceController(Context context, String key) { super(context, key); final String packageName = context.getPackageManager().getAttentionServicePackageName(); mIntent = new Intent(android.provider.Settings.ACTION_APPLICATION_DETAILS_SETTINGS); mIntent.setData(Uri.parse("package:" + packageName)); } @Override @AvailabilityStatus public int getAvailabilityStatus() { return AVAILABLE_UNSEARCHABLE; } @Override public boolean handlePreferenceTreeClick(Preference preference) { if (TextUtils.equals(getPreferenceKey(), preference.getKey())) { mContext.startActivity(mIntent); return true; } return super.handlePreferenceTreeClick(preference); } @Override public void updateState(Preference preference) { super.updateState(preference); if (TextUtils.equals(getPreferenceKey(), preference.getKey())) { preference.setVisible(!hasSufficientPermission(mContext.getPackageManager())); } } }
src/com/android/settings/display/AdaptiveSleepSettings.java +6 −51 Original line number Diff line number Diff line Loading @@ -16,21 +16,16 @@ 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.Intent; import android.content.pm.PackageManager; import android.net.Uri; import android.os.Bundle; import android.provider.SearchIndexableResource; 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 @@ -45,11 +40,6 @@ 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) { Loading @@ -57,32 +47,22 @@ public class AdaptiveSleepSettings extends DashboardFragment { final FooterPreference footerPreference = mFooterPreferenceMixin.createFooterPreference(); mContext = getContext(); mPermissionRequiredPreference = createPermissionMissionPreference(); footerPreference.setIcon(R.drawable.ic_privacy_shield_24dp); footerPreference.setTitle(R.string.adaptive_sleep_privacy); getPreferenceScreen().addPreference(mPermissionRequiredPreference); mPermissionRequiredPreference.setVisible(false); mPackageManager = mContext.getPackageManager(); mPackageName = mPackageManager.getAttentionServicePackageName(); Preference permissionPreference = findPreference( AdaptiveSleepPermissionPreferenceController.PREF_NAME); if (permissionPreference != null) { permissionPreference.setVisible(false); } 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 @@ -113,29 +93,4 @@ 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→tests/robotests/src/com/android/settings/display/AdaptiveSleepPermissionPreferenceControllerTest.java +23 −20 Original line number Diff line number Diff line Loading @@ -16,65 +16,68 @@ package com.android.settings.display; import static com.android.settings.core.BasePreferenceController.AVAILABLE_UNSEARCHABLE; import static com.google.common.truth.Truth.assertThat; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; import android.Manifest; import android.content.Context; import android.content.pm.PackageManager; import androidx.preference.PreferenceScreen; import androidx.preference.Preference; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.Mockito; 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"; public class AdaptiveSleepPermissionPreferenceControllerTest { private final static String PACKAGE_NAME = "package_name"; private AdaptiveSleepPermissionPreferenceController mController; @Mock private PackageManager mPackageManager; @Mock private PreferenceScreen mScreen; private Preference mPreference; @Before public void setUp() { MockitoAnnotations.initMocks(this); Context context = RuntimeEnvironment.application; mSettings = spy(new AdaptiveSleepSettings()); Context context = Mockito.spy(RuntimeEnvironment.application); doReturn(mPackageManager).when(context).getPackageManager(); 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); mController = new AdaptiveSleepPermissionPreferenceController(context, "test_key"); doReturn(mController.getPreferenceKey()).when(mPreference).getKey(); } @Test public void getAvailabilityStatus_returnAvailableUnsearchable() { assertThat(mController.getAvailabilityStatus()).isEqualTo(AVAILABLE_UNSEARCHABLE); } @Test public void onResume_hasPermission_preferenceInvisible() { mSettings.onResume(); public void updateStates_permissionGranted_preferenceInvisible() { mController.updateState(mPreference); assertThat(mSettings.mPermissionRequiredPreference.isVisible()).isFalse(); verify(mPreference).setVisible(false); } @Test public void onResume_noPermission_preferenceVisible() { public void updateStates_permissionRevoked_preferenceVisible() { doReturn(PackageManager.PERMISSION_DENIED).when(mPackageManager).checkPermission( Manifest.permission.CAMERA, PACKAGE_NAME); mSettings.onResume(); mController.updateState(mPreference); assertThat(mSettings.mPermissionRequiredPreference.isVisible()).isTrue(); verify(mPreference).setVisible(true); } }