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