Loading res/layout/activity_clock_face_picker.xml 0 → 100644 +29 −0 Original line number Diff line number Diff line <?xml version="1.0" encoding="utf-8"?> <!-- 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. --> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <FrameLayout android:id="@+id/fragment_container" android:layout_width="match_parent" android:layout_height="match_parent"/> </FrameLayout> robolectric_tests/src/com/android/customization/model/clock/BaseClockManagerTest.java 0 → 100644 +111 −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.customization.model.clock; import static junit.framework.TestCase.assertTrue; import static junit.framework.TestCase.fail; import static org.junit.Assert.assertEquals; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Matchers.anyBoolean; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import androidx.annotation.Nullable; import com.android.customization.model.CustomizationManager.Callback; 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; @RunWith(RobolectricTestRunner.class) public class BaseClockManagerTest { private static final String CURRENT_CLOCK = "current_clock"; @Mock ClockProvider mProvider; private TestClockManager mManager; @Before public void setUp() { MockitoAnnotations.initMocks(this); mManager = new TestClockManager(mProvider); } @Test public void testIsAvailable() { // GIVEN that the ClockProvider is available when(mProvider.isAvailable()).thenReturn(true); // THEN the BaseClockManager is true assertTrue(mManager.isAvailable()); } @Test public void testApply() { final String id = "id"; Clockface clock = new Clockface.Builder().setId(id).build(); mManager.apply(clock, new Callback() { @Override public void onSuccess() { //Nothing to do here, the test passed } @Override public void onError(@Nullable Throwable throwable) { fail("onError was called when grid had been applied successfully"); } }); assertEquals(id, mManager.getClockId()); } @Test public void testFetch() { mManager.fetchOptions(null, false); verify(mProvider).fetch(eq(null), anyBoolean()); } /** * Testable BaseClockManager that provides basic implementations of abstract methods. */ private static final class TestClockManager extends BaseClockManager { private String mClockId; TestClockManager(ClockProvider provider) { super(provider); } String getClockId() { return mClockId; } @Override protected void handleApply(Clockface option, Callback callback) { mClockId = option.getId(); callback.onSuccess(); } @Override protected String lookUpCurrentClock() { return CURRENT_CLOCK; } } } robolectric_tests/src/com/android/customization/model/clock/ClockManagerTest.java 0 → 100644 +84 −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.customization.model.clock; import static junit.framework.TestCase.fail; import static org.junit.Assert.assertEquals; import static org.mockito.Mockito.verify; import android.content.ContentResolver; import android.provider.Settings.Secure; import androidx.annotation.Nullable; import com.android.customization.model.CustomizationManager.Callback; import com.android.customization.module.ThemesUserEventLogger; 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 ClockManagerTest { private static final String CLOCK_ID = "id"; @Mock ClockProvider mProvider; @Mock ThemesUserEventLogger mLogger; private ContentResolver mContentResolver; private ClockManager mManager; @Before public void setUp() { MockitoAnnotations.initMocks(this); mContentResolver = RuntimeEnvironment.application.getContentResolver(); mManager = new ClockManager(mContentResolver, mProvider, mLogger); } @Test public void testApply() { Clockface clock = new Clockface.Builder().setId(CLOCK_ID).build(); mManager.apply(clock, new Callback() { @Override public void onSuccess() { //Nothing to do here, the test passed } @Override public void onError(@Nullable Throwable throwable) { fail("onError was called when grid had been applied successfully"); } }); // THEN the clock id is written to secure settings. assertEquals(CLOCK_ID, Secure.getString(mContentResolver, ClockManager.CLOCK_FACE_SETTING)); // AND the event is logged verify(mLogger).logClockApplied(clock); } @Test public void testGetCurrentClock() { // GIVEN that secure settings contains a clock id Secure.putString(mContentResolver, ClockManager.CLOCK_FACE_SETTING, CLOCK_ID); // THEN the current clock is that id assertEquals(CLOCK_ID, mManager.getCurrentClock()); } } src/com/android/customization/model/clock/BaseClockManager.java 0 → 100644 +65 −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.customization.model.clock; import com.android.customization.model.CustomizationManager; /** * {@link CustomizationManager} for clock faces. */ public abstract class BaseClockManager implements CustomizationManager<Clockface> { private final ClockProvider mClockProvider; public BaseClockManager(ClockProvider provider) { mClockProvider = provider; } @Override public boolean isAvailable() { return mClockProvider.isAvailable(); } @Override public void apply(Clockface option, Callback callback) { handleApply(option, callback); } @Override public void fetchOptions(OptionsFetchedListener<Clockface> callback, boolean reload) { mClockProvider.fetch(callback, false); } /** Returns the ID of the current clock face, which may be null for the default clock face. */ String getCurrentClock() { return lookUpCurrentClock(); } /** * Implement to apply the clock picked by the user for {@link BaseClockManager#apply}. * * @param option Clock option, containing ID of the clock, that the user picked. * @param callback Report success and failure. */ protected abstract void handleApply(Clockface option, Callback callback); /** * Implement to look up the current clock face for {@link BaseClockManager#getCurrentClock()}. * * @return ID of current clock. Can be null for the default clock face. */ protected abstract String lookUpCurrentClock(); } src/com/android/customization/model/clock/ClockManager.java +15 −23 Original line number Diff line number Diff line Loading @@ -15,35 +15,31 @@ */ package com.android.customization.model.clock; import android.content.Context; import android.content.ContentResolver; import android.provider.Settings.Secure; import com.android.customization.model.CustomizationManager; import com.android.customization.module.ThemesUserEventLogger; public class ClockManager implements CustomizationManager<Clockface> { /** * {@link CustomizationManager} for clock faces that implements apply by writing to secure settings. */ public class ClockManager extends BaseClockManager { // TODO: use constant from Settings.Secure private static final String CLOCK_FACE_SETTING = "lock_screen_custom_clock_face"; private final ClockProvider mClockProvider; private final Context mContext; static final String CLOCK_FACE_SETTING = "lock_screen_custom_clock_face"; private final ContentResolver mContentResolver; private final ThemesUserEventLogger mEventLogger; public ClockManager(Context context, ClockProvider provider, ThemesUserEventLogger logger) { mClockProvider = provider; mContext = context; public ClockManager(ContentResolver resolver, ClockProvider provider, ThemesUserEventLogger logger) { super(provider); mContentResolver = resolver; mEventLogger = logger; } @Override public boolean isAvailable() { return mClockProvider.isAvailable(); } @Override public void apply(Clockface option, Callback callback) { boolean stored = Secure.putString(mContext.getContentResolver(), CLOCK_FACE_SETTING, option.getId()); protected void handleApply(Clockface option, Callback callback) { boolean stored = Secure.putString(mContentResolver, CLOCK_FACE_SETTING, option.getId()); if (stored) { mEventLogger.logClockApplied(option); callback.onSuccess(); Loading @@ -53,11 +49,7 @@ public class ClockManager implements CustomizationManager<Clockface> { } @Override public void fetchOptions(OptionsFetchedListener<Clockface> callback, boolean reload) { mClockProvider.fetch(callback, false); } public String getCurrentClock() { return Secure.getString(mContext.getContentResolver(), CLOCK_FACE_SETTING); protected String lookUpCurrentClock() { return Secure.getString(mContentResolver, CLOCK_FACE_SETTING); } } Loading
res/layout/activity_clock_face_picker.xml 0 → 100644 +29 −0 Original line number Diff line number Diff line <?xml version="1.0" encoding="utf-8"?> <!-- 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. --> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <FrameLayout android:id="@+id/fragment_container" android:layout_width="match_parent" android:layout_height="match_parent"/> </FrameLayout>
robolectric_tests/src/com/android/customization/model/clock/BaseClockManagerTest.java 0 → 100644 +111 −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.customization.model.clock; import static junit.framework.TestCase.assertTrue; import static junit.framework.TestCase.fail; import static org.junit.Assert.assertEquals; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Matchers.anyBoolean; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import androidx.annotation.Nullable; import com.android.customization.model.CustomizationManager.Callback; 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; @RunWith(RobolectricTestRunner.class) public class BaseClockManagerTest { private static final String CURRENT_CLOCK = "current_clock"; @Mock ClockProvider mProvider; private TestClockManager mManager; @Before public void setUp() { MockitoAnnotations.initMocks(this); mManager = new TestClockManager(mProvider); } @Test public void testIsAvailable() { // GIVEN that the ClockProvider is available when(mProvider.isAvailable()).thenReturn(true); // THEN the BaseClockManager is true assertTrue(mManager.isAvailable()); } @Test public void testApply() { final String id = "id"; Clockface clock = new Clockface.Builder().setId(id).build(); mManager.apply(clock, new Callback() { @Override public void onSuccess() { //Nothing to do here, the test passed } @Override public void onError(@Nullable Throwable throwable) { fail("onError was called when grid had been applied successfully"); } }); assertEquals(id, mManager.getClockId()); } @Test public void testFetch() { mManager.fetchOptions(null, false); verify(mProvider).fetch(eq(null), anyBoolean()); } /** * Testable BaseClockManager that provides basic implementations of abstract methods. */ private static final class TestClockManager extends BaseClockManager { private String mClockId; TestClockManager(ClockProvider provider) { super(provider); } String getClockId() { return mClockId; } @Override protected void handleApply(Clockface option, Callback callback) { mClockId = option.getId(); callback.onSuccess(); } @Override protected String lookUpCurrentClock() { return CURRENT_CLOCK; } } }
robolectric_tests/src/com/android/customization/model/clock/ClockManagerTest.java 0 → 100644 +84 −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.customization.model.clock; import static junit.framework.TestCase.fail; import static org.junit.Assert.assertEquals; import static org.mockito.Mockito.verify; import android.content.ContentResolver; import android.provider.Settings.Secure; import androidx.annotation.Nullable; import com.android.customization.model.CustomizationManager.Callback; import com.android.customization.module.ThemesUserEventLogger; 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 ClockManagerTest { private static final String CLOCK_ID = "id"; @Mock ClockProvider mProvider; @Mock ThemesUserEventLogger mLogger; private ContentResolver mContentResolver; private ClockManager mManager; @Before public void setUp() { MockitoAnnotations.initMocks(this); mContentResolver = RuntimeEnvironment.application.getContentResolver(); mManager = new ClockManager(mContentResolver, mProvider, mLogger); } @Test public void testApply() { Clockface clock = new Clockface.Builder().setId(CLOCK_ID).build(); mManager.apply(clock, new Callback() { @Override public void onSuccess() { //Nothing to do here, the test passed } @Override public void onError(@Nullable Throwable throwable) { fail("onError was called when grid had been applied successfully"); } }); // THEN the clock id is written to secure settings. assertEquals(CLOCK_ID, Secure.getString(mContentResolver, ClockManager.CLOCK_FACE_SETTING)); // AND the event is logged verify(mLogger).logClockApplied(clock); } @Test public void testGetCurrentClock() { // GIVEN that secure settings contains a clock id Secure.putString(mContentResolver, ClockManager.CLOCK_FACE_SETTING, CLOCK_ID); // THEN the current clock is that id assertEquals(CLOCK_ID, mManager.getCurrentClock()); } }
src/com/android/customization/model/clock/BaseClockManager.java 0 → 100644 +65 −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.customization.model.clock; import com.android.customization.model.CustomizationManager; /** * {@link CustomizationManager} for clock faces. */ public abstract class BaseClockManager implements CustomizationManager<Clockface> { private final ClockProvider mClockProvider; public BaseClockManager(ClockProvider provider) { mClockProvider = provider; } @Override public boolean isAvailable() { return mClockProvider.isAvailable(); } @Override public void apply(Clockface option, Callback callback) { handleApply(option, callback); } @Override public void fetchOptions(OptionsFetchedListener<Clockface> callback, boolean reload) { mClockProvider.fetch(callback, false); } /** Returns the ID of the current clock face, which may be null for the default clock face. */ String getCurrentClock() { return lookUpCurrentClock(); } /** * Implement to apply the clock picked by the user for {@link BaseClockManager#apply}. * * @param option Clock option, containing ID of the clock, that the user picked. * @param callback Report success and failure. */ protected abstract void handleApply(Clockface option, Callback callback); /** * Implement to look up the current clock face for {@link BaseClockManager#getCurrentClock()}. * * @return ID of current clock. Can be null for the default clock face. */ protected abstract String lookUpCurrentClock(); }
src/com/android/customization/model/clock/ClockManager.java +15 −23 Original line number Diff line number Diff line Loading @@ -15,35 +15,31 @@ */ package com.android.customization.model.clock; import android.content.Context; import android.content.ContentResolver; import android.provider.Settings.Secure; import com.android.customization.model.CustomizationManager; import com.android.customization.module.ThemesUserEventLogger; public class ClockManager implements CustomizationManager<Clockface> { /** * {@link CustomizationManager} for clock faces that implements apply by writing to secure settings. */ public class ClockManager extends BaseClockManager { // TODO: use constant from Settings.Secure private static final String CLOCK_FACE_SETTING = "lock_screen_custom_clock_face"; private final ClockProvider mClockProvider; private final Context mContext; static final String CLOCK_FACE_SETTING = "lock_screen_custom_clock_face"; private final ContentResolver mContentResolver; private final ThemesUserEventLogger mEventLogger; public ClockManager(Context context, ClockProvider provider, ThemesUserEventLogger logger) { mClockProvider = provider; mContext = context; public ClockManager(ContentResolver resolver, ClockProvider provider, ThemesUserEventLogger logger) { super(provider); mContentResolver = resolver; mEventLogger = logger; } @Override public boolean isAvailable() { return mClockProvider.isAvailable(); } @Override public void apply(Clockface option, Callback callback) { boolean stored = Secure.putString(mContext.getContentResolver(), CLOCK_FACE_SETTING, option.getId()); protected void handleApply(Clockface option, Callback callback) { boolean stored = Secure.putString(mContentResolver, CLOCK_FACE_SETTING, option.getId()); if (stored) { mEventLogger.logClockApplied(option); callback.onSuccess(); Loading @@ -53,11 +49,7 @@ public class ClockManager implements CustomizationManager<Clockface> { } @Override public void fetchOptions(OptionsFetchedListener<Clockface> callback, boolean reload) { mClockProvider.fetch(callback, false); } public String getCurrentClock() { return Secure.getString(mContext.getContentResolver(), CLOCK_FACE_SETTING); protected String lookUpCurrentClock() { return Secure.getString(mContentResolver, CLOCK_FACE_SETTING); } }