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