Home | History | Annotate | Download | only in terms
      1 /*
      2  * Copyright 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.managedprovisioning.preprovisioning.terms;
     17 
     18 import static com.android.internal.util.Preconditions.checkNotNull;
     19 
     20 import android.text.Spanned;
     21 import android.text.method.LinkMovementMethod;
     22 import android.view.LayoutInflater;
     23 import android.view.View;
     24 import android.view.ViewGroup;
     25 import android.view.accessibility.AccessibilityNodeInfo;
     26 import android.widget.BaseExpandableListAdapter;
     27 import android.widget.ImageView;
     28 import android.widget.TextView;
     29 
     30 import com.android.managedprovisioning.R;
     31 import com.android.managedprovisioning.common.AccessibilityContextMenuMaker;
     32 import com.android.managedprovisioning.common.HtmlToSpannedParser;
     33 
     34 import java.util.List;
     35 
     36 /**
     37  * Allows for displaying {@link TermsDocument} objects in an
     38  * {@link android.widget.ExpandableListView}.
     39  */
     40 class TermsListAdapter extends BaseExpandableListAdapter {
     41     private final List<TermsDocument> mTermsDocuments;
     42     private final LayoutInflater mInflater;
     43     private final HtmlToSpannedParser mHtmlToSpannedParser;
     44     private final AccessibilityContextMenuMaker mContextMenuMaker;
     45     private final GroupExpandedInfo mGroupExpandedInfo;
     46 
     47     /**
     48      * Creates a new instance of the class.
     49      */
     50     TermsListAdapter(List<TermsDocument> termsDocuments, LayoutInflater layoutInflater,
     51             AccessibilityContextMenuMaker contextMenuMaker, HtmlToSpannedParser htmlToSpannedParser,
     52             GroupExpandedInfo groupExpandedInfo) {
     53         mTermsDocuments = checkNotNull(termsDocuments);
     54         mInflater = checkNotNull(layoutInflater);
     55         mHtmlToSpannedParser = checkNotNull(htmlToSpannedParser);
     56         mGroupExpandedInfo = checkNotNull(groupExpandedInfo);
     57         mContextMenuMaker = checkNotNull(contextMenuMaker);
     58     }
     59 
     60     @Override
     61     public int getGroupCount() {
     62         return mTermsDocuments.size();
     63     }
     64 
     65     @Override
     66     public int getChildrenCount(int groupPosition) {
     67         return 1; // one content piece per header
     68     }
     69 
     70     @Override
     71     public TermsDocument getGroup(int groupPosition) {
     72         return getDisclaimer(groupPosition);
     73     }
     74 
     75     @Override
     76     public TermsDocument getChild(int groupPosition, int childPosition) {
     77         return getDisclaimer(groupPosition);
     78     }
     79 
     80     @Override
     81     public long getGroupId(int groupPosition) {
     82         return groupPosition;
     83     }
     84 
     85     @Override
     86     public long getChildId(int groupPosition, int childPosition) {
     87         return childPosition;
     88     }
     89 
     90     @Override
     91     public boolean hasStableIds() {
     92         return true;
     93     }
     94 
     95     // TODO: encapsulate this logic - too much direct view manipulation
     96     @Override
     97     public View getGroupView(int groupPosition, boolean isExpanded, View convertView,
     98             ViewGroup parent) {
     99         String heading = getDisclaimer(groupPosition).getHeading();
    100 
    101         View groupView = convertView != null ? convertView : mInflater.inflate(
    102                 R.layout.terms_disclaimer_header, parent, false);
    103         groupView.setContentDescription(
    104                 parent.getResources().getString(R.string.section_heading, heading));
    105         groupView.setAccessibilityDelegate(new View.AccessibilityDelegate() {
    106             @Override public void onInitializeAccessibilityNodeInfo(View host,
    107                     AccessibilityNodeInfo info) {
    108                 super.onInitializeAccessibilityNodeInfo(host, info);
    109                 info.addAction(new AccessibilityNodeInfo.AccessibilityAction(
    110                         AccessibilityNodeInfo.AccessibilityAction.ACTION_CLICK.getId(),
    111                         parent.getResources().getString(
    112                                 isExpanded ? R.string.collapse : R.string.expand)));
    113             }
    114         });
    115 
    116         TextView textView = groupView.findViewById(R.id.header_text);
    117         textView.setText(heading);
    118 
    119         ImageView chevron = groupView.findViewById(R.id.chevron);
    120         chevron.setRotation(isExpanded ? 90 : -90); // chevron down / up retrospectively
    121         groupView.findViewById(R.id.divider).setVisibility(
    122                 shouldShowGroupDivider(groupPosition) ? View.VISIBLE : View.INVISIBLE);
    123 
    124         return groupView;
    125     }
    126 
    127     /**
    128      * Helps avoid a double thick divider line: one above header, one from the bottom of prev child
    129      */
    130     private boolean shouldShowGroupDivider(int groupPosition) {
    131         return mGroupExpandedInfo.isGroupExpanded(groupPosition)
    132                 && (groupPosition == 0 || !mGroupExpandedInfo.isGroupExpanded(groupPosition - 1));
    133     }
    134 
    135     // TODO: encapsulate this logic - too much direct view manipulation
    136     @Override
    137     public View getChildView(int groupPosition, int childPosition, boolean isLastChild,
    138             View convertView, ViewGroup parent) {
    139         View view = convertView != null ? convertView : mInflater.inflate(
    140                 R.layout.terms_disclaimer_content, parent, false);
    141 
    142         TermsDocument disclaimer = getDisclaimer(groupPosition);
    143         TextView textView = view.findViewById(R.id.disclaimer_content);
    144         Spanned content = mHtmlToSpannedParser.parseHtml(disclaimer.getContent());
    145         textView.setText(content);
    146         textView.setContentDescription(
    147                 parent.getResources().getString(R.string.section_content, disclaimer.getHeading(),
    148                         content));
    149         textView.setMovementMethod(LinkMovementMethod.getInstance()); // makes html links clickable
    150         mContextMenuMaker.registerWithActivity(textView);
    151         return view;
    152     }
    153 
    154     private TermsDocument getDisclaimer(int index) {
    155         return mTermsDocuments.get(index);
    156     }
    157 
    158     @Override
    159     public boolean isChildSelectable(int groupPosition, int childPosition) {
    160         return false;
    161     }
    162 
    163     interface GroupExpandedInfo {
    164         boolean isGroupExpanded(int groupPosition);
    165     }
    166 }