1 /*
2  * Copyright (C) 2015 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 
17 package com.android.messaging.ui.mediapicker;
18 
19 import android.app.FragmentManager;
20 import android.content.Context;
21 import androidx.appcompat.app.ActionBar;
22 import android.view.LayoutInflater;
23 import android.view.Menu;
24 import android.view.MenuInflater;
25 import android.view.MenuItem;
26 import android.view.View;
27 import android.view.ViewGroup;
28 import android.widget.ImageButton;
29 
30 import com.android.messaging.R;
31 import com.android.messaging.datamodel.binding.ImmutableBindingRef;
32 import com.android.messaging.datamodel.data.MediaPickerData;
33 import com.android.messaging.datamodel.data.DraftMessageData.DraftMessageSubscriptionDataProvider;
34 import com.android.messaging.ui.BasePagerViewHolder;
35 import com.android.messaging.util.Assert;
36 import com.android.messaging.util.OsUtil;
37 
38 abstract class MediaChooser extends BasePagerViewHolder
39         implements DraftMessageSubscriptionDataProvider {
40     /** The media picker that the chooser is hosted in */
41     protected final MediaPicker mMediaPicker;
42 
43     /** Referencing the main media picker binding to perform data loading */
44     protected final ImmutableBindingRef<MediaPickerData> mBindingRef;
45 
46     /** True if this is the selected chooser */
47     protected boolean mSelected;
48 
49     /** True if this chooser is open */
50     protected boolean mOpen;
51 
52     /** The button to show in the tab strip */
53     private ImageButton mTabButton;
54 
55     /** Used by subclasses to indicate that no loader is required from the data model in order for
56      * this chooser to function.
57      */
58     public static final int NO_LOADER_REQUIRED = -1;
59 
60     /**
61      * Initializes a new instance of the Chooser class
62      * @param mediaPicker The media picker that the chooser is hosted in
63      */
MediaChooser(final MediaPicker mediaPicker)64     MediaChooser(final MediaPicker mediaPicker) {
65         Assert.notNull(mediaPicker);
66         mMediaPicker = mediaPicker;
67         mBindingRef = mediaPicker.getMediaPickerDataBinding();
68         mSelected = false;
69     }
70 
setSelected(final boolean selected)71     protected void setSelected(final boolean selected) {
72         mSelected = selected;
73         if (selected) {
74             // If we're selected, it must be open
75             mOpen = true;
76         }
77         if (mTabButton != null) {
78             mTabButton.setSelected(selected);
79             mTabButton.setAlpha(selected ? 1 : 0.5f);
80         }
81     }
82 
getTabButton()83     ImageButton getTabButton() {
84         return mTabButton;
85     }
86 
onCreateTabButton(final LayoutInflater inflater, final ViewGroup parent)87     void onCreateTabButton(final LayoutInflater inflater, final ViewGroup parent) {
88         mTabButton = (ImageButton) inflater.inflate(
89                 R.layout.mediapicker_tab_button,
90                 parent,
91                 false /* addToParent */);
92         mTabButton.setImageResource(getIconResource());
93         mTabButton.setContentDescription(
94                 inflater.getContext().getResources().getString(getIconDescriptionResource()));
95         setSelected(mSelected);
96         mTabButton.setOnClickListener(new View.OnClickListener() {
97             @Override
98             public void onClick(final View view) {
99                 mMediaPicker.selectChooser(MediaChooser.this);
100             }
101         });
102     }
103 
getContext()104     protected Context getContext() {
105         return mMediaPicker.getActivity();
106     }
107 
getFragmentManager()108     protected FragmentManager getFragmentManager() {
109         return OsUtil.isAtLeastJB_MR1() ? mMediaPicker.getChildFragmentManager() :
110                 mMediaPicker.getFragmentManager();
111     }
getLayoutInflater()112     protected LayoutInflater getLayoutInflater() {
113         return LayoutInflater.from(getContext());
114     }
115 
116     /** Allows the chooser to handle full screen change */
onFullScreenChanged(final boolean fullScreen)117     void onFullScreenChanged(final boolean fullScreen) {}
118 
119     /** Allows the chooser to handle the chooser being opened or closed */
onOpenedChanged(final boolean open)120     void onOpenedChanged(final boolean open) {
121         mOpen = open;
122     }
123 
124     /** @return The bit field of media types that this chooser can pick */
getSupportedMediaTypes()125     public abstract int getSupportedMediaTypes();
126 
127     /** @return The resource id of the icon for the chooser */
getIconResource()128     abstract int getIconResource();
129 
130     /** @return The resource id of the string to use for the accessibility text of the icon */
getIconDescriptionResource()131     abstract int getIconDescriptionResource();
132 
133     /**
134      * Sets up the action bar to show the current state of the full-screen chooser
135      * @param actionBar The action bar to populate
136      */
updateActionBar(final ActionBar actionBar)137     void updateActionBar(final ActionBar actionBar) {
138         final int actionBarTitleResId = getActionBarTitleResId();
139         if (actionBarTitleResId == 0) {
140             actionBar.hide();
141         } else {
142             actionBar.setCustomView(null);
143             actionBar.setDisplayOptions(ActionBar.DISPLAY_SHOW_TITLE);
144             actionBar.setDisplayHomeAsUpEnabled(true);
145             actionBar.show();
146             // Use X instead of <- in the action bar
147             actionBar.setHomeAsUpIndicator(R.drawable.ic_remove_small_light);
148             actionBar.setTitle(actionBarTitleResId);
149         }
150     }
151 
152     /**
153      * Returns the resource Id used for the action bar title.
154      */
getActionBarTitleResId()155     abstract int getActionBarTitleResId();
156 
157     /**
158      * Throws an exception if the media chooser object doesn't require data support.
159      */
onDataUpdated(final Object data, final int loaderId)160     public void onDataUpdated(final Object data, final int loaderId) {
161         throw new IllegalStateException();
162     }
163 
164     /**
165      * Called by the MediaPicker to determine whether this panel can be swiped down further. If
166      * not, then a swipe down gestured will be captured by the MediaPickerPanel to shrink the
167      * entire panel.
168      */
canSwipeDown()169     public boolean canSwipeDown() {
170         return false;
171     }
172 
173     /**
174      * Typically the media picker is closed when the IME is opened, but this allows the chooser to
175      * specify that showing the IME is okay while the chooser is up
176      */
canShowIme()177     public boolean canShowIme() {
178         return false;
179     }
180 
onBackPressed()181     public boolean onBackPressed() {
182         return false;
183     }
184 
onCreateOptionsMenu(final MenuInflater inflater, final Menu menu)185     public void onCreateOptionsMenu(final MenuInflater inflater, final Menu menu) {
186     }
187 
onOptionsItemSelected(final MenuItem item)188     public boolean onOptionsItemSelected(final MenuItem item) {
189         return false;
190     }
191 
setThemeColor(final int color)192     public void setThemeColor(final int color) {
193     }
194 
195     /**
196      * Returns true if the chooser is owning any incoming touch events, so that the media picker
197      * panel won't process it and slide the panel.
198      */
isHandlingTouch()199     public boolean isHandlingTouch() {
200         return false;
201     }
202 
stopTouchHandling()203     public void stopTouchHandling() {
204     }
205 
206     @Override
getConversationSelfSubId()207     public int getConversationSelfSubId() {
208         return mMediaPicker.getConversationSelfSubId();
209     }
210 
211     /** Optional activity life-cycle methods to be overridden by subclasses */
onPause()212     public void onPause() { }
onResume()213     public void onResume() { }
onRequestPermissionsResult( final int requestCode, final String permissions[], final int[] grantResults)214     protected void onRequestPermissionsResult(
215             final int requestCode, final String permissions[], final int[] grantResults) { }
216 }
217