1 /*
2  * Copyright (C) 2016 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package com.android.emergency.view;
17 
18 import androidx.fragment.app.Fragment;
19 import androidx.fragment.app.FragmentActivity;
20 import androidx.fragment.app.FragmentManager;
21 import android.content.Context;
22 import android.content.Intent;
23 import android.content.SharedPreferences;
24 import android.graphics.Bitmap;
25 import android.graphics.drawable.Drawable;
26 import android.os.Bundle;
27 import androidx.annotation.LayoutRes;
28 import android.os.UserHandle;
29 import android.os.UserManager;
30 import com.google.android.material.tabs.TabLayout;
31 import com.google.android.material.tabs.TabLayout.TabLayoutOnPageChangeListener;
32 import com.google.android.material.tabs.TabLayout.ViewPagerOnTabSelectedListener;
33 import androidx.fragment.app.FragmentStatePagerAdapter;
34 import androidx.viewpager.widget.ViewPager;
35 import androidx.preference.PreferenceManager;
36 import android.text.TextUtils;
37 import android.util.Pair;
38 import android.view.Menu;
39 import android.view.MenuInflater;
40 import android.view.MenuItem;
41 import android.view.View;
42 import android.widget.ImageView;
43 import android.widget.LinearLayout;
44 import android.widget.TextView;
45 import android.widget.Toolbar;
46 import android.widget.ViewFlipper;
47 
48 import com.android.emergency.CircleFramedDrawable;
49 import com.android.emergency.R;
50 import com.android.emergency.edit.EditInfoActivity;
51 import com.android.emergency.util.PreferenceUtils;
52 import com.android.internal.annotations.VisibleForTesting;
53 import com.android.internal.logging.MetricsLogger;
54 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
55 import com.android.internal.util.UserIcons;
56 
57 import java.util.ArrayList;
58 
59 /**
60  * Activity for viewing emergency information.
61  */
62 public class ViewInfoActivity extends FragmentActivity {
63     private ImageView mPersonalCardLargeIcon;
64     private TextView mPersonalCardLargeItem;
65     private SharedPreferences mSharedPreferences;
66     private LinearLayout mPersonalCard;
67     private ViewFlipper mViewFlipper;
68     private ViewPagerAdapter mTabsAdapter;
69     private TabLayout mTabLayout;
70     private ArrayList<Pair<String, Fragment>> mFragments;
71     private Menu mMenu;
72 
73     @Override
setContentView(@ayoutRes int layoutResID)74     public void setContentView(@LayoutRes int layoutResID) {
75         super.setContentView(layoutResID);
76         setupTabs();
77         Toolbar toolbar = (Toolbar) findViewById(R.id.action_bar);
78         setActionBar(toolbar);
79         getActionBar().setDisplayHomeAsUpEnabled(true);
80     }
81 
82     @Override
onCreate(Bundle savedInstanceState)83     protected void onCreate(Bundle savedInstanceState) {
84         super.onCreate(savedInstanceState);
85         setContentView(R.layout.view_activity_layout);
86         mSharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
87         mPersonalCard = (LinearLayout) findViewById(R.id.name_and_dob_linear_layout);
88         mPersonalCardLargeIcon = (ImageView) findViewById(R.id.personal_card_icon);
89         mPersonalCardLargeItem = (TextView) findViewById(R.id.personal_card_large);
90         mViewFlipper = (ViewFlipper) findViewById(R.id.view_flipper);
91 
92         MetricsLogger.visible(this, MetricsEvent.ACTION_VIEW_EMERGENCY_INFO);
93     }
94 
95     @Override
onResume()96     public void onResume() {
97         super.onResume();
98         loadUserInfo();
99         // Update the tabs: new info might have been added/deleted from the edit screen that
100         // could lead to adding/removing a fragment
101         setupTabs();
102         maybeHideTabs();
103     }
104 
loadUserInfo()105     private void loadUserInfo() {
106         UserManager userManager = getSystemService(UserManager.class);
107         if (TextUtils.isEmpty(userManager.getUserName())) {
108             mPersonalCard.setVisibility(View.GONE);
109         } else {
110             mPersonalCard.setVisibility(View.VISIBLE);
111             mPersonalCardLargeItem.setText(userManager.getUserName());
112 
113             Bitmap bitmapUserIcon = userManager.getUserIcon(UserHandle.myUserId());
114 
115             if (bitmapUserIcon == null) {
116                 // Get default user icon.
117                 Drawable defaultUserIcon = UserIcons.getDefaultUserIcon(
118                         getApplicationContext().getResources(), UserHandle.myUserId(),
119                         false /* light icon */);
120                 bitmapUserIcon = UserIcons.convertToBitmap(defaultUserIcon);
121             }
122 
123             Drawable drawableUserIcon = new CircleFramedDrawable(bitmapUserIcon,
124                     (int) getResources().getDimension(R.dimen.action_bar_size));
125 
126             mPersonalCardLargeIcon.setImageDrawable(drawableUserIcon);
127         }
128     }
129 
maybeHideTabs()130     private void maybeHideTabs() {
131         // Show a TextView with "No information provided" if there are no fragments.
132         if (mFragments.size() == 0) {
133             mViewFlipper.setDisplayedChild(
134                     mViewFlipper.indexOfChild(findViewById(R.id.no_info)));
135         } else {
136             mViewFlipper.setDisplayedChild(mViewFlipper.indexOfChild(findViewById(R.id.tabs)));
137         }
138 
139         TabLayout tabLayout = mTabLayout;
140         if (mFragments.size() <= 1) {
141             tabLayout.setVisibility(View.GONE);
142         } else {
143             tabLayout.setVisibility(View.VISIBLE);
144         }
145     }
146 
147     @Override
onCreateOptionsMenu(Menu menu)148     public boolean onCreateOptionsMenu(Menu menu) {
149         MenuInflater inflater = getMenuInflater();
150         inflater.inflate(R.menu.view_info_menu, menu);
151         mMenu = menu;
152         return super.onCreateOptionsMenu(menu);
153     }
154 
155     @Override
onOptionsItemSelected(MenuItem item)156     public boolean onOptionsItemSelected(MenuItem item) {
157         int itemId = item.getItemId();
158         if (itemId == android.R.id.home) {
159             onBackPressed();
160             return true;
161         } else if (itemId == R.id.action_edit) {
162             Intent intent = new Intent(this, EditInfoActivity.class);
163             intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
164             startActivity(intent);
165             return true;
166         }
167         return super.onOptionsItemSelected(item);
168     }
169 
170     /** Return the tab layout. */
171     @VisibleForTesting
getTabLayout()172     public TabLayout getTabLayout() {
173         return mTabLayout;
174     }
175 
176     @VisibleForTesting
getMenu()177     public Menu getMenu() {
178         return mMenu;
179     }
180 
181     /** Return the fragments. */
182     @VisibleForTesting
getFragments()183     public ArrayList<Pair<String, Fragment>> getFragments() {
184         return mFragments;
185     }
186 
setUpFragments()187     private ArrayList<Pair<String, Fragment>> setUpFragments() {
188         // Return only the fragments that have at least one piece of information set:
189         ArrayList<Pair<String, Fragment>> fragments = new ArrayList<>(2);
190 
191         if (PreferenceUtils.hasAtLeastOnePreferenceSet(this)) {
192             fragments.add(Pair.create(getResources().getString(R.string.tab_title_info),
193                     ViewEmergencyInfoFragment.newInstance()));
194         }
195         if (PreferenceUtils.hasAtLeastOneEmergencyContact(this)) {
196             fragments.add(Pair.create(getResources().getString(R.string.tab_title_contacts),
197                     ViewEmergencyContactsFragment.newInstance()));
198         }
199         return fragments;
200     }
201 
setupTabs()202     private void setupTabs() {
203         mFragments = setUpFragments();
204         mTabLayout = (TabLayout) findViewById(R.id.sliding_tabs);
205         if (mTabsAdapter == null) {
206             // The viewpager that will host the section contents.
207             ViewPager viewPager = (ViewPager) findViewById(R.id.view_pager);
208             mTabsAdapter = new ViewPagerAdapter(getSupportFragmentManager());
209             viewPager.setAdapter(mTabsAdapter);
210             mTabLayout.setTabsFromPagerAdapter(mTabsAdapter);
211 
212             // Set a listener via setOnTabSelectedListener(OnTabSelectedListener) to be notified
213             // when any tab's selection state has been changed.
214             mTabLayout.setOnTabSelectedListener(
215                     new TabLayout.ViewPagerOnTabSelectedListener(viewPager));
216 
217             // Use a TabLayout.TabLayoutOnPageChangeListener to forward the scroll and selection
218             // changes to this layout
219             viewPager.addOnPageChangeListener(new TabLayoutOnPageChangeListener(mTabLayout));
220         } else {
221             mTabsAdapter.notifyDataSetChanged();
222             mTabLayout.setTabsFromPagerAdapter(mTabsAdapter);
223         }
224     }
225 
226     /** The adapter used to handle the two fragments. */
227     protected class ViewPagerAdapter extends FragmentStatePagerAdapter {
ViewPagerAdapter(FragmentManager fm)228         public ViewPagerAdapter(FragmentManager fm) {
229             super(fm);
230         }
231 
232         @Override
getItem(int position)233         public Fragment getItem(int position) {
234             return mFragments.get(position).second;
235         }
236 
237         @Override
getCount()238         public int getCount() {
239             return mFragments.size();
240         }
241 
242         @Override
getPageTitle(int position)243         public CharSequence getPageTitle(int position) {
244             return mFragments.get(position).first;
245         }
246 
247         @Override
getItemPosition(Object object)248         public int getItemPosition(Object object) {
249             // The default implementation assumes that items will never change position and always
250             // returns POSITION_UNCHANGED. This is how you can specify that the positions can change
251             return FragmentStatePagerAdapter.POSITION_NONE;
252         }
253     }
254 }
255