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