OSDN Git Service

Added the icon displayed on no account in search bar
authorSunny Shao <sunnyshao@google.com>
Tue, 30 Oct 2018 03:55:15 +0000 (11:55 +0800)
committerSunny Shao <sunnyshao@google.com>
Mon, 5 Nov 2018 02:52:11 +0000 (10:52 +0800)
Mofidied the search_bar layout and added this icon in the right side of the search_bar.
Added the hasAccount api in AvatarViewMixin and display this icon when there is no any account in device.
Added the test case of the AvatarViewMixin.

Bug: 117509285
Test: robotest
Change-Id: I6ceaa457af4fb20acd0211ca840df5b530c47e0f

res/drawable/ic_account_circle_24dp.xml [new file with mode: 0644]
res/layout/search_bar.xml
res/values/dimens.xml
src/com/android/settings/accounts/AvatarViewMixin.java [new file with mode: 0644]
src/com/android/settings/homepage/SettingsHomepageActivity.java
tests/robotests/src/com/android/settings/accounts/AvatarViewMixinTest.java [new file with mode: 0644]

diff --git a/res/drawable/ic_account_circle_24dp.xml b/res/drawable/ic_account_circle_24dp.xml
new file mode 100644 (file)
index 0000000..8445adc
--- /dev/null
@@ -0,0 +1,27 @@
+<!--
+  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.
+  -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="32dp"
+    android:height="32dp"
+    android:viewportWidth="24"
+    android:viewportHeight="24">
+  <path
+      android:fillColor="#ff4285f4"
+      android:pathData="M12,2C6.48,2 2,6.48 2,12c0,5.52 4.48,10 10,10c5.52,0 10,-4.48 10,-10C22,6.48 17.52,2 12,2zM7.07,18.28c0.43,-0.9 3.05,-1.78 4.93,-1.78s4.51,0.88 4.93,1.78C15.57,19.36 13.86,20 12,20S8.43,19.36 7.07,18.28zM18.36,16.83c-1.43,-1.74 -4.9,-2.33 -6.36,-2.33s-4.93,0.59 -6.36,2.33C4.62,15.49 4,13.82 4,12c0,-4.41 3.59,-8 8,-8c4.41,0 8,3.59 8,8C20,13.82 19.38,15.49 18.36,16.83z"/>
+  <path
+      android:fillColor="#ff4285f4"
+      android:pathData="M12,6c-1.94,0 -3.5,1.56 -3.5,3.5S10.06,13 12,13c1.94,0 3.5,-1.56 3.5,-3.5S13.94,6 12,6zM12,11c-0.83,0 -1.5,-0.67 -1.5,-1.5C10.5,8.67 11.17,8 12,8c0.83,0 1.5,0.67 1.5,1.5C13.5,10.33 12.83,11 12,11z"/>
+</vector>
index 9e64db7..1ba64ad 100644 (file)
                 android:layout_height="wrap_content"
                 android:text="@string/search_menu"/>
         </Toolbar>
+        <ImageView
+            android:id="@+id/account_avatar"
+            android:layout_marginStart="@dimen/search_bar_avatar_start_margin"
+            android:layout_marginEnd="@dimen/search_bar_avatar_end_margin"
+            android:layout_width="@dimen/search_bar_avatar_size"
+            android:layout_height="@dimen/search_bar_avatar_size"
+            android:layout_gravity="end|center_vertical"/>
     </androidx.cardview.widget.CardView>
 </FrameLayout>
\ No newline at end of file
index 9b33388..43cae81 100755 (executable)
     <dimen name="search_bar_text_size">16dp</dimen>
     <dimen name="search_bar_card_elevation">2dp</dimen>
     <dimen name="search_bar_content_inset">64dp</dimen>
+    <dimen name="search_bar_avatar_size">32dp</dimen>
+    <dimen name="search_bar_avatar_start_margin">4dp</dimen>
+    <dimen name="search_bar_avatar_end_margin">16dp</dimen>
 
     <!-- Dimensions for Wifi Assistant Card -->
     <dimen name="wifi_assistant_padding_top_bottom">16dp</dimen>
diff --git a/src/com/android/settings/accounts/AvatarViewMixin.java b/src/com/android/settings/accounts/AvatarViewMixin.java
new file mode 100644 (file)
index 0000000..d7f6f8a
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+ * 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.accounts;
+
+import android.accounts.Account;
+import android.content.Context;
+import android.widget.ImageView;
+
+import androidx.annotation.VisibleForTesting;
+import androidx.lifecycle.Lifecycle;
+import androidx.lifecycle.LifecycleObserver;
+import androidx.lifecycle.OnLifecycleEvent;
+
+import com.android.settings.R;
+import com.android.settings.homepage.SettingsHomepageActivity;
+import com.android.settings.overlay.FeatureFactory;
+
+/**
+ * Avatar related work to the onStart method of registered observable classes
+ * in {@link SettingsHomepageActivity}.
+ */
+public class AvatarViewMixin implements LifecycleObserver {
+    private Context mContext;
+    private ImageView mAvatarView;
+
+    public AvatarViewMixin(Context context, ImageView avatarView) {
+        mContext = context.getApplicationContext();
+        mAvatarView = avatarView;
+    }
+
+    @OnLifecycleEvent(Lifecycle.Event.ON_START)
+    public void onStart() {
+        if (hasAccount()) {
+            //TODO(b/117509285): To migrate account icon on search bar
+        } else {
+            mAvatarView.setImageResource(R.drawable.ic_account_circle_24dp);
+        }
+    }
+
+    @VisibleForTesting
+    boolean hasAccount() {
+        final Account accounts[] = FeatureFactory.getFactory(
+                mContext).getAccountFeatureProvider().getAccounts(mContext);
+        return (accounts != null) && (accounts.length > 0);
+    }
+}
index c10543d..d3f11a0 100644 (file)
@@ -19,6 +19,7 @@ package com.android.settings.homepage;
 import android.content.Intent;
 import android.os.Bundle;
 import android.util.FeatureFlagUtils;
+import android.widget.ImageView;
 import android.widget.Toolbar;
 
 import androidx.fragment.app.Fragment;
@@ -27,6 +28,7 @@ import androidx.fragment.app.FragmentTransaction;
 
 import com.android.settings.R;
 import com.android.settings.SettingsActivity;
+import com.android.settings.accounts.AvatarViewMixin;
 import com.android.settings.core.FeatureFlags;
 import com.android.settings.core.SettingsBaseActivity;
 import com.android.settings.homepage.contextualcards.ContextualCardsFragment;
@@ -51,6 +53,10 @@ public class SettingsHomepageActivity extends SettingsBaseActivity {
         FeatureFactory.getFactory(this).getSearchFeatureProvider()
                 .initSearchToolbar(this, toolbar);
 
+        final ImageView avatarView = findViewById(R.id.account_avatar);
+        final AvatarViewMixin avatarViewMixin = new AvatarViewMixin(this, avatarView);
+        getLifecycle().addObserver(avatarViewMixin);
+
         showFragment(new ContextualCardsFragment(), R.id.contextual_cards_content);
         showFragment(new TopLevelSettings(), R.id.main_content);
     }
diff --git a/tests/robotests/src/com/android/settings/accounts/AvatarViewMixinTest.java b/tests/robotests/src/com/android/settings/accounts/AvatarViewMixinTest.java
new file mode 100644 (file)
index 0000000..c72561e
--- /dev/null
@@ -0,0 +1,94 @@
+/*
+ * 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.accounts;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+
+import android.accounts.Account;
+import android.content.Context;
+import android.widget.ImageView;
+
+import com.android.settings.homepage.SettingsHomepageActivity;
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.Robolectric;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.android.controller.ActivityController;
+import org.robolectric.annotation.Config;
+import org.robolectric.annotation.Implementation;
+import org.robolectric.annotation.Implements;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+public class AvatarViewMixinTest {
+    private static final String DUMMY_ACCOUNT = "test@domain.com";
+    private static final String DUMMY_DOMAIN = "domain.com";
+
+    private Context mContext;
+    private ImageView mImageView;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        mContext = RuntimeEnvironment.application;
+        mImageView = new ImageView(mContext);
+    }
+
+    @Test
+    public void hasAccount_useDefaultAccountData_returnFalse() {
+        final AvatarViewMixin avatarViewMixin = new AvatarViewMixin(mContext, mImageView);
+        assertThat(avatarViewMixin.hasAccount()).isFalse();
+    }
+
+    @Test
+    @Config(shadows = ShadowAccountFeatureProviderImpl.class)
+    public void hasAccount_useShadowAccountData_returnTrue() {
+        final AvatarViewMixin avatarViewMixin = new AvatarViewMixin(mContext, mImageView);
+        assertThat(avatarViewMixin.hasAccount()).isTrue();
+    }
+
+    @Test
+    public void onStart_useMockAvatarViewMixin_shouldBeExecuted() {
+        final AvatarViewMixin mockAvatar = spy(new AvatarViewMixin(mContext, mImageView));
+
+        final ActivityController controller = Robolectric.buildActivity(
+                SettingsHomepageActivity.class).create();
+        final SettingsHomepageActivity settingsHomepageActivity =
+                (SettingsHomepageActivity) controller.get();
+        settingsHomepageActivity.getLifecycle().addObserver(mockAvatar);
+        controller.start();
+
+        verify(mockAvatar).onStart();
+    }
+
+    @Implements(AccountFeatureProviderImpl.class)
+    public static class ShadowAccountFeatureProviderImpl {
+
+        @Implementation
+        public Account[] getAccounts(Context context) {
+            Account[] accounts = {new Account(DUMMY_ACCOUNT, DUMMY_DOMAIN)};
+            return accounts;
+        }
+    }
+}