1 /* 2 * Copyright (C) 2014 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.tv.settings.dialog.old; 18 19 import android.content.Context; 20 import android.content.Intent; 21 import android.content.pm.PackageManager; 22 import android.content.res.Resources; 23 import android.graphics.drawable.Drawable; 24 import android.net.Uri; 25 import android.os.Parcel; 26 import android.os.Parcelable; 27 import android.util.Log; 28 29 import java.util.ArrayList; 30 31 /** 32 * An action within an {@link ActionAdapter}. 33 */ 34 public class Action implements Parcelable { 35 36 private static final String TAG = "Action"; 37 38 public static final int NO_DRAWABLE = 0; 39 public static final int NO_CHECK_SET = 0; 40 public static final int DEFAULT_CHECK_SET_ID = 1; 41 42 private final String mKey; 43 private final String mTitle; 44 private final String mDescription; 45 private final Intent mIntent; 46 47 /** 48 * If not {@code null}, the package name to use to retrieve {{@link #mDrawableResource}. 49 */ 50 private final String mResourcePackageName; 51 52 private final int mDrawableResource; 53 private final Uri mIconUri; 54 private boolean mChecked; 55 private final boolean mMultilineDescription; 56 private final boolean mHasNext; 57 private final boolean mInfoOnly; 58 private final int mCheckSetId; 59 private boolean mEnabled; 60 61 /** 62 * Builds a Action object. 63 */ 64 public static class Builder { 65 private String mKey; 66 private String mTitle; 67 private String mDescription; 68 private Intent mIntent; 69 private String mResourcePackageName; 70 private int mDrawableResource = NO_DRAWABLE; 71 private Uri mIconUri; 72 private boolean mChecked; 73 private boolean mMultilineDescription; 74 private boolean mHasNext; 75 private boolean mInfoOnly; 76 private int mCheckSetId = NO_CHECK_SET; 77 private boolean mEnabled = true; 78 build()79 public Action build() { 80 return new Action( 81 mKey, 82 mTitle, 83 mDescription, 84 mResourcePackageName, 85 mDrawableResource, 86 mIconUri, 87 mChecked, 88 mMultilineDescription, 89 mHasNext, 90 mInfoOnly, 91 mIntent, 92 mCheckSetId, 93 mEnabled); 94 } 95 key(String key)96 public Builder key(String key) { 97 mKey = key; 98 return this; 99 } 100 title(String title)101 public Builder title(String title) { 102 mTitle = title; 103 return this; 104 } 105 description(String description)106 public Builder description(String description) { 107 mDescription = description; 108 return this; 109 } 110 intent(Intent intent)111 public Builder intent(Intent intent) { 112 mIntent = intent; 113 return this; 114 } 115 resourcePackageName(String resourcePackageName)116 public Builder resourcePackageName(String resourcePackageName) { 117 mResourcePackageName = resourcePackageName; 118 return this; 119 } 120 drawableResource(int drawableResource)121 public Builder drawableResource(int drawableResource) { 122 mDrawableResource = drawableResource; 123 return this; 124 } 125 iconUri(Uri iconUri)126 public Builder iconUri(Uri iconUri) { 127 mIconUri = iconUri; 128 return this; 129 } 130 checked(boolean checked)131 public Builder checked(boolean checked) { 132 mChecked = checked; 133 return this; 134 } 135 multilineDescription(boolean multilineDescription)136 public Builder multilineDescription(boolean multilineDescription) { 137 mMultilineDescription = multilineDescription; 138 return this; 139 } 140 hasNext(boolean hasNext)141 public Builder hasNext(boolean hasNext) { 142 mHasNext = hasNext; 143 return this; 144 } 145 infoOnly(boolean infoOnly)146 public Builder infoOnly(boolean infoOnly) { 147 mInfoOnly = infoOnly; 148 return this; 149 } 150 checkSetId(int checkSetId)151 public Builder checkSetId(int checkSetId) { 152 mCheckSetId = checkSetId; 153 return this; 154 } 155 enabled(boolean enabled)156 public Builder enabled(boolean enabled) { 157 mEnabled = enabled; 158 return this; 159 } 160 } 161 Action(String key, String title, String description, String resourcePackageName, int drawableResource, Uri iconUri, boolean checked, boolean multilineDescription, boolean hasNext, boolean infoOnly, Intent intent, int checkSetId, boolean enabled)162 protected Action(String key, String title, String description, String resourcePackageName, 163 int drawableResource, Uri iconUri, boolean checked, boolean multilineDescription, 164 boolean hasNext, boolean infoOnly, Intent intent, int checkSetId, boolean enabled) { 165 mKey = key; 166 mTitle = title; 167 mDescription = description; 168 mResourcePackageName = resourcePackageName; 169 mDrawableResource = drawableResource; 170 mIconUri = iconUri; 171 mChecked = checked; 172 mMultilineDescription = multilineDescription; 173 mHasNext = hasNext; 174 mInfoOnly = infoOnly; 175 mIntent = intent; 176 mCheckSetId = checkSetId; 177 mEnabled = enabled; 178 } 179 180 /** 181 * Returns a list of {@link Action} with the specified keys and titles 182 * matched up. 183 * <p> 184 * The key and title arrays must be of equal length. 185 */ createActionsFromArrays(String[] keys, String[] titles)186 public static ArrayList<Action> createActionsFromArrays(String[] keys, String[] titles) { 187 return createActionsFromArrays(keys, titles, NO_CHECK_SET, null); 188 } 189 190 /** 191 * Returns a list of {@link Action} with the specified keys and titles 192 * matched up and a given check set ID so that they are related. 193 * <p> 194 * The key and title arrays must be of equal length. 195 */ createActionsFromArrays(String[] keys, String[] titles, int checkSetId, String checkedItemKey)196 public static ArrayList<Action> createActionsFromArrays(String[] keys, String[] titles, 197 int checkSetId, String checkedItemKey) { 198 int keysLength = keys.length; 199 int titlesLength = titles.length; 200 201 if (keysLength != titlesLength) { 202 throw new IllegalArgumentException("Keys and titles dimensions must match"); 203 } 204 205 ArrayList<Action> actions = new ArrayList<Action>(); 206 for (int i = 0; i < keysLength; i++) { 207 Action.Builder builder = new Action.Builder(); 208 builder.key(keys[i]).title(titles[i]).checkSetId(checkSetId); 209 if (checkedItemKey != null) { 210 if (checkedItemKey.equals(keys[i])) { 211 builder.checked(true); 212 } else { 213 builder.checked(false); 214 } 215 } 216 Action action = builder.build(); 217 actions.add(action); 218 } 219 return actions; 220 } 221 getKey()222 public String getKey() { 223 return mKey; 224 } 225 getTitle()226 public String getTitle() { 227 return mTitle; 228 } 229 getDescription()230 public String getDescription() { 231 return mDescription; 232 } 233 getIntent()234 public Intent getIntent() { 235 return mIntent; 236 } 237 isChecked()238 public boolean isChecked() { 239 return mChecked; 240 } 241 getIconUri()242 public Uri getIconUri() { 243 return mIconUri; 244 } 245 246 /** 247 * Returns the check set id this action is a part of. All actions in the same list with the 248 * same check set id are considered linked. When one of the actions within that set is selected 249 * that action becomes checked while all the other actions become unchecked. 250 * @return an integer representing the check set this action is a part of or {@NO_CHECK_SET} if 251 * this action isn't a part of a check set. 252 */ getCheckSetId()253 public int getCheckSetId() { 254 return mCheckSetId; 255 } 256 hasMultilineDescription()257 public boolean hasMultilineDescription() { 258 return mMultilineDescription; 259 } 260 isEnabled()261 public boolean isEnabled() { 262 return mEnabled; 263 } 264 setChecked(boolean checked)265 public void setChecked(boolean checked) { 266 mChecked = checked; 267 } 268 setEnabled(boolean enabled)269 public void setEnabled(boolean enabled) { 270 mEnabled = enabled; 271 } 272 273 /** 274 * @return true if the action will request further user input when selected 275 * (such as showing another dialog or launching a new activity). 276 * False, otherwise. 277 */ hasNext()278 public boolean hasNext() { 279 return mHasNext; 280 } 281 282 /** 283 * @return true if the action will only display information and is thus unactionable. 284 * If both this and {@link #hasNext()} are true, infoOnly takes precedence. (default is false) 285 * e.g. Play balance, or cost of an app. 286 */ infoOnly()287 public boolean infoOnly() { 288 return mInfoOnly; 289 } 290 291 /** 292 * Returns an indicator to be drawn. If null is returned, no space for the 293 * indicator will be made. 294 * 295 * @param context the context of the Activity this Action belongs to 296 * @return an indicator to draw or null if no indicator space should exist. 297 */ getIndicator(Context context)298 public Drawable getIndicator(Context context) { 299 if (mDrawableResource == NO_DRAWABLE) { 300 return null; 301 } 302 if (mResourcePackageName == null) { 303 return context.getDrawable(mDrawableResource); 304 } 305 // If we get to here, need to load the resources. 306 Drawable icon = null; 307 try { 308 Context packageContext = context.createPackageContext(mResourcePackageName, 0); 309 icon = packageContext.getDrawable(mDrawableResource); 310 } catch (PackageManager.NameNotFoundException e) { 311 if (Log.isLoggable(TAG, Log.WARN)) { 312 Log.w(TAG, "No icon for this action."); 313 } 314 } catch (Resources.NotFoundException e) { 315 if (Log.isLoggable(TAG, Log.WARN)) { 316 Log.w(TAG, "No icon for this action."); 317 } 318 } 319 return icon; 320 } 321 322 public static Parcelable.Creator<Action> CREATOR = new Parcelable.Creator<Action>() { 323 324 @Override 325 public Action createFromParcel(Parcel source) { 326 327 return new Action.Builder() 328 .key(source.readString()) 329 .title(source.readString()) 330 .description(source.readString()) 331 .intent((Intent) source.readParcelable(Intent.class.getClassLoader())) 332 .resourcePackageName(source.readString()) 333 .drawableResource(source.readInt()) 334 .iconUri((Uri) source.readParcelable(Uri.class.getClassLoader())) 335 .checked(source.readInt() != 0) 336 .multilineDescription(source.readInt() != 0) 337 .checkSetId(source.readInt()) 338 .build(); 339 } 340 341 @Override 342 public Action[] newArray(int size) { 343 return new Action[size]; 344 } 345 }; 346 347 @Override describeContents()348 public int describeContents() { 349 return 0; 350 } 351 352 @Override writeToParcel(Parcel dest, int flags)353 public void writeToParcel(Parcel dest, int flags) { 354 dest.writeString(mKey); 355 dest.writeString(mTitle); 356 dest.writeString(mDescription); 357 dest.writeParcelable(mIntent, flags); 358 dest.writeString(mResourcePackageName); 359 dest.writeInt(mDrawableResource); 360 dest.writeParcelable(mIconUri, flags); 361 dest.writeInt(mChecked ? 1 : 0); 362 dest.writeInt(mMultilineDescription ? 1 : 0); 363 dest.writeInt(mCheckSetId); 364 } 365 } 366