/* * Copyright (C) 2016 Google Inc. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.google.android.apps.santatracker.launch; import android.app.UiModeManager; import android.content.Context; import android.content.Intent; import android.content.res.Configuration; import android.support.annotation.StringRes; import android.view.View; import android.widget.Toast; import com.google.android.apps.santatracker.R; import com.google.android.apps.santatracker.util.SantaLog; /** * Partial implementation of a launch from the main village into a specific game or activity. All * launches are visually illustrated with a marker and must be defined with color, a badge and some * state that defines whether the marker is locked or available. */ public abstract class AbstractLaunch implements View.OnClickListener, View.OnLongClickListener, VoiceAction.VoiceActionHandler { public static final int STATE_LOCKED = 0; public static final int STATE_READY = 1; public static final int STATE_DISABLED = 2; public static final int STATE_FINISHED = 3; public static final int STATE_HIDDEN = 4; private static final String TAG = "AbstractLaunch"; protected int mState = STATE_DISABLED; protected SantaContext mContext; protected String mContentDescription; protected int mCardDrawable; protected View mClickTarget; private LauncherDataChangedCallback mLauncherCallback; private View mLockedView; /** * Constructs a new launch (marker). * * @param context The application (Santa) context * @param contentDescriptionId The name of the marker, used for accessibility * @param cardDrawable The resource ID of the card to draw */ public AbstractLaunch(SantaContext context, LauncherDataChangedCallback adapter, int contentDescriptionId, int cardDrawable) { initialise(context, adapter, contentDescriptionId, cardDrawable); } protected void initialise(SantaContext context, LauncherDataChangedCallback adapter, int contentDescriptionId, int cardDrawable) { setContext(context); mLauncherCallback = adapter; mState = STATE_DISABLED; mContentDescription = mContext.getResources().getString(contentDescriptionId); mCardDrawable = cardDrawable; } /** Sets the SantaContext. */ public void setContext(SantaContext context) { mContext = context; mState = STATE_DISABLED; } public void attachToView(View view) { mClickTarget = view; mClickTarget.setOnClickListener(this); } public int getCardResource() { return mCardDrawable; } public View getClickTarget() { return mClickTarget; } public String getContentDescription() { return mContentDescription; } /** Attaches events to the marker, updating the image based on the current state. */ public void applyState() { if (mLockedView != null) { if (mState == STATE_DISABLED || mState == STATE_LOCKED || mState == STATE_FINISHED) { mLockedView.setVisibility(View.VISIBLE); } else { mLockedView.setVisibility(View.GONE); } } } public void setLockedView(View lockedView) { mLockedView = lockedView; } /** * Updates the state of the image (e.g. locked). * * @param state One of {@code STATE_LOCKED, STATE_READY, STATE_DISABLED, STATE_FINISHED, * STATE_HIDDEN} */ public void setState(int state) { if (mState != state) { mState = state; applyState(); mLauncherCallback.refreshData(); } } /** * Display a {@link android.widget.Toast} with a given string resource message. */ protected void notify(Context context, int stringId) { notify(context, context.getResources().getText(stringId).toString()); } /** * Display a {@link android.widget.Toast} with a given string resource message with additional * string parameters. * * @see android.content.res.Resources#getString(int, Object...) */ protected void notify(Context context, int stringId, Object... args) { notify(context, context.getResources().getString(stringId, args)); } /** * Display a {@link android.widget.Toast} with a given string. */ protected void notify(Context context, String string) { Toast.makeText(context, string, Toast.LENGTH_SHORT).show(); } /** Retrieves the current marker state. */ public int getState() { return mState; } /** * Convenience method used for launching games. * Simulate onClick event if the intent received is of the type specified by * actionName and the extra value matches the content description of the current * instance. * * @param intent the intent to examine * @param actionName the action name, for example VoiceAction.ACTION_PLAY_GAME * @param extraName the extra name, for example VoiceAction.ACTION_PLAY_GAME_EXTRA * @return true if matched and OnClick was invoked */ protected boolean clickIfMatchesDescription(Intent intent, String actionName, String extraName) { String action = intent.getAction(); if (actionName.equals(action)) { String description = intent.getStringExtra(extraName); if (mContentDescription.equalsIgnoreCase(description)) { SantaLog.d(TAG, String.format("Voice command: [%s] [%s]", actionName, description)); onClick(mClickTarget); return true; } } return false; } public String getVerb() { return mContext.getResources().getString(R.string.play); } /** * Handles a voice action. Override if the implementation wishes to handle voice actions and * return true if it has been or will be handled. * * @param intent Google Now Actions intent. * @return true if the action was handled or will be handled */ @Override public boolean handleVoiceAction(Intent intent) { return false; } /** * Determines if this marker is a game. Default is true, so override is only necessary if * implementation is not a game. * * @return true if this launcher will launch a game, false otherwise. */ public boolean isGame() { return true; } /** Checck whether the app is running on Tv or not. */ protected boolean isTV() { final Context context = mContext.getApplicationContext(); UiModeManager manager = (UiModeManager) context.getSystemService(Context.UI_MODE_SERVICE); return manager.getCurrentModeType() == Configuration.UI_MODE_TYPE_TELEVISION; } /** * Get a string message explaining that the game is unavailable. */ protected String getDisabledString(@StringRes int gameNameId) { String gameName = mContext.getResources().getString(gameNameId); return mContext.getResources().getString(R.string.generic_game_disabled, gameName); } }