Wed, 31 Dec 2014 06:09:35 +0100
Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.
michael@0 | 1 | /* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*- |
michael@0 | 2 | * This Source Code Form is subject to the terms of the Mozilla Public |
michael@0 | 3 | * License, v. 2.0. If a copy of the MPL was not distributed with this |
michael@0 | 4 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
michael@0 | 5 | |
michael@0 | 6 | package org.mozilla.gecko.home; |
michael@0 | 7 | |
michael@0 | 8 | import java.util.ArrayList; |
michael@0 | 9 | import java.util.EnumSet; |
michael@0 | 10 | import java.util.List; |
michael@0 | 11 | |
michael@0 | 12 | import org.mozilla.gecko.R; |
michael@0 | 13 | import org.mozilla.gecko.Telemetry; |
michael@0 | 14 | import org.mozilla.gecko.TelemetryContract; |
michael@0 | 15 | import org.mozilla.gecko.animation.PropertyAnimator; |
michael@0 | 16 | import org.mozilla.gecko.animation.ViewHelper; |
michael@0 | 17 | import org.mozilla.gecko.home.HomeAdapter.OnAddPanelListener; |
michael@0 | 18 | import org.mozilla.gecko.home.HomeConfig.PanelConfig; |
michael@0 | 19 | import org.mozilla.gecko.util.ThreadUtils; |
michael@0 | 20 | |
michael@0 | 21 | import android.content.Context; |
michael@0 | 22 | import android.graphics.drawable.Drawable; |
michael@0 | 23 | import android.os.Build; |
michael@0 | 24 | import android.os.Bundle; |
michael@0 | 25 | import android.support.v4.app.FragmentManager; |
michael@0 | 26 | import android.support.v4.app.LoaderManager; |
michael@0 | 27 | import android.support.v4.app.LoaderManager.LoaderCallbacks; |
michael@0 | 28 | import android.support.v4.content.Loader; |
michael@0 | 29 | import android.support.v4.view.ViewPager; |
michael@0 | 30 | import android.util.AttributeSet; |
michael@0 | 31 | import android.view.MotionEvent; |
michael@0 | 32 | import android.view.View; |
michael@0 | 33 | import android.view.ViewGroup; |
michael@0 | 34 | |
michael@0 | 35 | public class HomePager extends ViewPager { |
michael@0 | 36 | private static final int LOADER_ID_CONFIG = 0; |
michael@0 | 37 | |
michael@0 | 38 | private final Context mContext; |
michael@0 | 39 | private volatile boolean mVisible; |
michael@0 | 40 | private Decor mDecor; |
michael@0 | 41 | private View mTabStrip; |
michael@0 | 42 | private HomeBanner mHomeBanner; |
michael@0 | 43 | private int mDefaultPageIndex = -1; |
michael@0 | 44 | |
michael@0 | 45 | private final OnAddPanelListener mAddPanelListener; |
michael@0 | 46 | |
michael@0 | 47 | private final HomeConfig mConfig; |
michael@0 | 48 | private ConfigLoaderCallbacks mConfigLoaderCallbacks; |
michael@0 | 49 | |
michael@0 | 50 | private String mInitialPanelId; |
michael@0 | 51 | |
michael@0 | 52 | // Cached original ViewPager background. |
michael@0 | 53 | private final Drawable mOriginalBackground; |
michael@0 | 54 | |
michael@0 | 55 | // Telemetry session for current panel. |
michael@0 | 56 | private String mCurrentPanelSession; |
michael@0 | 57 | |
michael@0 | 58 | // Current load state of HomePager. |
michael@0 | 59 | private LoadState mLoadState; |
michael@0 | 60 | |
michael@0 | 61 | // Listens for when the current panel changes. |
michael@0 | 62 | private OnPanelChangeListener mPanelChangedListener; |
michael@0 | 63 | |
michael@0 | 64 | // This is mostly used by UI tests to easily fetch |
michael@0 | 65 | // specific list views at runtime. |
michael@0 | 66 | static final String LIST_TAG_HISTORY = "history"; |
michael@0 | 67 | static final String LIST_TAG_BOOKMARKS = "bookmarks"; |
michael@0 | 68 | static final String LIST_TAG_READING_LIST = "reading_list"; |
michael@0 | 69 | static final String LIST_TAG_TOP_SITES = "top_sites"; |
michael@0 | 70 | static final String LIST_TAG_MOST_RECENT = "most_recent"; |
michael@0 | 71 | static final String LIST_TAG_LAST_TABS = "last_tabs"; |
michael@0 | 72 | static final String LIST_TAG_BROWSER_SEARCH = "browser_search"; |
michael@0 | 73 | |
michael@0 | 74 | public interface OnUrlOpenListener { |
michael@0 | 75 | public enum Flags { |
michael@0 | 76 | ALLOW_SWITCH_TO_TAB, |
michael@0 | 77 | OPEN_WITH_INTENT |
michael@0 | 78 | } |
michael@0 | 79 | |
michael@0 | 80 | public void onUrlOpen(String url, EnumSet<Flags> flags); |
michael@0 | 81 | } |
michael@0 | 82 | |
michael@0 | 83 | public interface OnNewTabsListener { |
michael@0 | 84 | public void onNewTabs(String[] urls); |
michael@0 | 85 | } |
michael@0 | 86 | |
michael@0 | 87 | /** |
michael@0 | 88 | * Interface for listening into ViewPager panel changes |
michael@0 | 89 | */ |
michael@0 | 90 | public interface OnPanelChangeListener { |
michael@0 | 91 | /** |
michael@0 | 92 | * Called when a new panel is selected. |
michael@0 | 93 | * |
michael@0 | 94 | * @param panelId of the newly selected panel |
michael@0 | 95 | */ |
michael@0 | 96 | public void onPanelSelected(String panelId); |
michael@0 | 97 | } |
michael@0 | 98 | |
michael@0 | 99 | interface OnTitleClickListener { |
michael@0 | 100 | public void onTitleClicked(int index); |
michael@0 | 101 | } |
michael@0 | 102 | |
michael@0 | 103 | /** |
michael@0 | 104 | * Special type of child views that could be added as pager decorations by default. |
michael@0 | 105 | */ |
michael@0 | 106 | interface Decor { |
michael@0 | 107 | public void onAddPagerView(String title); |
michael@0 | 108 | public void removeAllPagerViews(); |
michael@0 | 109 | public void onPageSelected(int position); |
michael@0 | 110 | public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels); |
michael@0 | 111 | public void setOnTitleClickListener(OnTitleClickListener onTitleClickListener); |
michael@0 | 112 | } |
michael@0 | 113 | |
michael@0 | 114 | /** |
michael@0 | 115 | * State of HomePager with respect to loading its configuration. |
michael@0 | 116 | */ |
michael@0 | 117 | private enum LoadState { |
michael@0 | 118 | UNLOADED, |
michael@0 | 119 | LOADING, |
michael@0 | 120 | LOADED |
michael@0 | 121 | } |
michael@0 | 122 | |
michael@0 | 123 | static final String CAN_LOAD_ARG = "canLoad"; |
michael@0 | 124 | static final String PANEL_CONFIG_ARG = "panelConfig"; |
michael@0 | 125 | |
michael@0 | 126 | public HomePager(Context context) { |
michael@0 | 127 | this(context, null); |
michael@0 | 128 | } |
michael@0 | 129 | |
michael@0 | 130 | public HomePager(Context context, AttributeSet attrs) { |
michael@0 | 131 | super(context, attrs); |
michael@0 | 132 | mContext = context; |
michael@0 | 133 | |
michael@0 | 134 | mConfig = HomeConfig.getDefault(mContext); |
michael@0 | 135 | mConfigLoaderCallbacks = new ConfigLoaderCallbacks(); |
michael@0 | 136 | |
michael@0 | 137 | mAddPanelListener = new OnAddPanelListener() { |
michael@0 | 138 | @Override |
michael@0 | 139 | public void onAddPanel(String title) { |
michael@0 | 140 | if (mDecor != null) { |
michael@0 | 141 | mDecor.onAddPagerView(title); |
michael@0 | 142 | } |
michael@0 | 143 | } |
michael@0 | 144 | }; |
michael@0 | 145 | |
michael@0 | 146 | // This is to keep all 4 panels in memory after they are |
michael@0 | 147 | // selected in the pager. |
michael@0 | 148 | setOffscreenPageLimit(3); |
michael@0 | 149 | |
michael@0 | 150 | // We can call HomePager.requestFocus to steal focus from the URL bar and drop the soft |
michael@0 | 151 | // keyboard. However, if there are no focusable views (e.g. an empty reading list), the |
michael@0 | 152 | // URL bar will be refocused. Therefore, we make the HomePager container focusable to |
michael@0 | 153 | // ensure there is always a focusable view. This would ordinarily be done via an XML |
michael@0 | 154 | // attribute, but it is not working properly. |
michael@0 | 155 | setFocusableInTouchMode(true); |
michael@0 | 156 | |
michael@0 | 157 | mOriginalBackground = getBackground(); |
michael@0 | 158 | setOnPageChangeListener(new PageChangeListener()); |
michael@0 | 159 | |
michael@0 | 160 | mLoadState = LoadState.UNLOADED; |
michael@0 | 161 | } |
michael@0 | 162 | |
michael@0 | 163 | @Override |
michael@0 | 164 | public void addView(View child, int index, ViewGroup.LayoutParams params) { |
michael@0 | 165 | if (child instanceof Decor) { |
michael@0 | 166 | ((ViewPager.LayoutParams) params).isDecor = true; |
michael@0 | 167 | mDecor = (Decor) child; |
michael@0 | 168 | mTabStrip = child; |
michael@0 | 169 | |
michael@0 | 170 | mDecor.setOnTitleClickListener(new OnTitleClickListener() { |
michael@0 | 171 | @Override |
michael@0 | 172 | public void onTitleClicked(int index) { |
michael@0 | 173 | setCurrentItem(index, true); |
michael@0 | 174 | } |
michael@0 | 175 | }); |
michael@0 | 176 | } else if (child instanceof HomePagerTabStrip) { |
michael@0 | 177 | mTabStrip = child; |
michael@0 | 178 | } |
michael@0 | 179 | |
michael@0 | 180 | super.addView(child, index, params); |
michael@0 | 181 | } |
michael@0 | 182 | |
michael@0 | 183 | /** |
michael@0 | 184 | * Loads and initializes the pager. |
michael@0 | 185 | * |
michael@0 | 186 | * @param fm FragmentManager for the adapter |
michael@0 | 187 | */ |
michael@0 | 188 | public void load(LoaderManager lm, FragmentManager fm, String panelId, PropertyAnimator animator) { |
michael@0 | 189 | mLoadState = LoadState.LOADING; |
michael@0 | 190 | |
michael@0 | 191 | mVisible = true; |
michael@0 | 192 | mInitialPanelId = panelId; |
michael@0 | 193 | |
michael@0 | 194 | // Update the home banner message each time the HomePager is loaded. |
michael@0 | 195 | if (mHomeBanner != null) { |
michael@0 | 196 | mHomeBanner.update(); |
michael@0 | 197 | } |
michael@0 | 198 | |
michael@0 | 199 | // Only animate on post-HC devices, when a non-null animator is given |
michael@0 | 200 | final boolean shouldAnimate = (animator != null && Build.VERSION.SDK_INT >= 11); |
michael@0 | 201 | |
michael@0 | 202 | final HomeAdapter adapter = new HomeAdapter(mContext, fm); |
michael@0 | 203 | adapter.setOnAddPanelListener(mAddPanelListener); |
michael@0 | 204 | adapter.setCanLoadHint(!shouldAnimate); |
michael@0 | 205 | setAdapter(adapter); |
michael@0 | 206 | |
michael@0 | 207 | // Don't show the tabs strip until we have the |
michael@0 | 208 | // list of panels in place. |
michael@0 | 209 | mTabStrip.setVisibility(View.INVISIBLE); |
michael@0 | 210 | |
michael@0 | 211 | // Load list of panels from configuration |
michael@0 | 212 | lm.initLoader(LOADER_ID_CONFIG, null, mConfigLoaderCallbacks); |
michael@0 | 213 | |
michael@0 | 214 | if (shouldAnimate) { |
michael@0 | 215 | animator.addPropertyAnimationListener(new PropertyAnimator.PropertyAnimationListener() { |
michael@0 | 216 | @Override |
michael@0 | 217 | public void onPropertyAnimationStart() { |
michael@0 | 218 | setLayerType(View.LAYER_TYPE_HARDWARE, null); |
michael@0 | 219 | } |
michael@0 | 220 | |
michael@0 | 221 | @Override |
michael@0 | 222 | public void onPropertyAnimationEnd() { |
michael@0 | 223 | setLayerType(View.LAYER_TYPE_NONE, null); |
michael@0 | 224 | adapter.setCanLoadHint(true); |
michael@0 | 225 | } |
michael@0 | 226 | }); |
michael@0 | 227 | |
michael@0 | 228 | ViewHelper.setAlpha(this, 0.0f); |
michael@0 | 229 | |
michael@0 | 230 | animator.attach(this, |
michael@0 | 231 | PropertyAnimator.Property.ALPHA, |
michael@0 | 232 | 1.0f); |
michael@0 | 233 | } |
michael@0 | 234 | Telemetry.startUISession(TelemetryContract.Session.HOME); |
michael@0 | 235 | } |
michael@0 | 236 | |
michael@0 | 237 | /** |
michael@0 | 238 | * Removes all child fragments to free memory. |
michael@0 | 239 | */ |
michael@0 | 240 | public void unload() { |
michael@0 | 241 | mVisible = false; |
michael@0 | 242 | setAdapter(null); |
michael@0 | 243 | mLoadState = LoadState.UNLOADED; |
michael@0 | 244 | |
michael@0 | 245 | // Stop UI Telemetry sessions. |
michael@0 | 246 | stopCurrentPanelTelemetrySession(); |
michael@0 | 247 | Telemetry.stopUISession(TelemetryContract.Session.HOME); |
michael@0 | 248 | } |
michael@0 | 249 | |
michael@0 | 250 | /** |
michael@0 | 251 | * Determines whether the pager is visible. |
michael@0 | 252 | * |
michael@0 | 253 | * Unlike getVisibility(), this method does not need to be called on the UI |
michael@0 | 254 | * thread. |
michael@0 | 255 | * |
michael@0 | 256 | * @return Whether the pager and its fragments are loaded |
michael@0 | 257 | */ |
michael@0 | 258 | public boolean isVisible() { |
michael@0 | 259 | return mVisible; |
michael@0 | 260 | } |
michael@0 | 261 | |
michael@0 | 262 | @Override |
michael@0 | 263 | public void setCurrentItem(int item, boolean smoothScroll) { |
michael@0 | 264 | super.setCurrentItem(item, smoothScroll); |
michael@0 | 265 | |
michael@0 | 266 | if (mDecor != null) { |
michael@0 | 267 | mDecor.onPageSelected(item); |
michael@0 | 268 | } |
michael@0 | 269 | |
michael@0 | 270 | if (mHomeBanner != null) { |
michael@0 | 271 | mHomeBanner.setActive(item == mDefaultPageIndex); |
michael@0 | 272 | } |
michael@0 | 273 | } |
michael@0 | 274 | |
michael@0 | 275 | /** |
michael@0 | 276 | * Shows a home panel. If the given panelId is null, |
michael@0 | 277 | * the default panel will be shown. No action will be taken if: |
michael@0 | 278 | * * HomePager has not loaded yet |
michael@0 | 279 | * * Panel with the given panelId cannot be found |
michael@0 | 280 | * |
michael@0 | 281 | * @param panelId of the home panel to be shown. |
michael@0 | 282 | */ |
michael@0 | 283 | public void showPanel(String panelId) { |
michael@0 | 284 | if (!mVisible) { |
michael@0 | 285 | return; |
michael@0 | 286 | } |
michael@0 | 287 | |
michael@0 | 288 | switch (mLoadState) { |
michael@0 | 289 | case LOADING: |
michael@0 | 290 | mInitialPanelId = panelId; |
michael@0 | 291 | break; |
michael@0 | 292 | |
michael@0 | 293 | case LOADED: |
michael@0 | 294 | int position = mDefaultPageIndex; |
michael@0 | 295 | if (panelId != null) { |
michael@0 | 296 | position = ((HomeAdapter) getAdapter()).getItemPosition(panelId); |
michael@0 | 297 | } |
michael@0 | 298 | |
michael@0 | 299 | if (position > -1) { |
michael@0 | 300 | setCurrentItem(position); |
michael@0 | 301 | } |
michael@0 | 302 | break; |
michael@0 | 303 | |
michael@0 | 304 | default: |
michael@0 | 305 | // Do nothing. |
michael@0 | 306 | } |
michael@0 | 307 | } |
michael@0 | 308 | |
michael@0 | 309 | @Override |
michael@0 | 310 | public boolean onInterceptTouchEvent(MotionEvent event) { |
michael@0 | 311 | if (event.getActionMasked() == MotionEvent.ACTION_DOWN) { |
michael@0 | 312 | // Drop the soft keyboard by stealing focus from the URL bar. |
michael@0 | 313 | requestFocus(); |
michael@0 | 314 | } |
michael@0 | 315 | |
michael@0 | 316 | return super.onInterceptTouchEvent(event); |
michael@0 | 317 | } |
michael@0 | 318 | |
michael@0 | 319 | public void setBanner(HomeBanner banner) { |
michael@0 | 320 | mHomeBanner = banner; |
michael@0 | 321 | } |
michael@0 | 322 | |
michael@0 | 323 | @Override |
michael@0 | 324 | public boolean dispatchTouchEvent(MotionEvent event) { |
michael@0 | 325 | if (mHomeBanner != null) { |
michael@0 | 326 | mHomeBanner.handleHomeTouch(event); |
michael@0 | 327 | } |
michael@0 | 328 | |
michael@0 | 329 | return super.dispatchTouchEvent(event); |
michael@0 | 330 | } |
michael@0 | 331 | |
michael@0 | 332 | public void onToolbarFocusChange(boolean hasFocus) { |
michael@0 | 333 | if (mHomeBanner == null) { |
michael@0 | 334 | return; |
michael@0 | 335 | } |
michael@0 | 336 | |
michael@0 | 337 | // We should only make the banner active if the toolbar is not focused and we are on the default page |
michael@0 | 338 | final boolean active = !hasFocus && getCurrentItem() == mDefaultPageIndex; |
michael@0 | 339 | mHomeBanner.setActive(active); |
michael@0 | 340 | } |
michael@0 | 341 | |
michael@0 | 342 | private void updateUiFromConfigState(HomeConfig.State configState) { |
michael@0 | 343 | // We only care about the adapter if HomePager is currently |
michael@0 | 344 | // loaded, which means it's visible in the activity. |
michael@0 | 345 | if (!mVisible) { |
michael@0 | 346 | return; |
michael@0 | 347 | } |
michael@0 | 348 | |
michael@0 | 349 | if (mDecor != null) { |
michael@0 | 350 | mDecor.removeAllPagerViews(); |
michael@0 | 351 | } |
michael@0 | 352 | |
michael@0 | 353 | final HomeAdapter adapter = (HomeAdapter) getAdapter(); |
michael@0 | 354 | |
michael@0 | 355 | // Disable any fragment loading until we have the initial |
michael@0 | 356 | // panel selection done. Store previous value to restore |
michael@0 | 357 | // it if necessary once the UI is fully updated. |
michael@0 | 358 | final boolean canLoadHint = adapter.getCanLoadHint(); |
michael@0 | 359 | adapter.setCanLoadHint(false); |
michael@0 | 360 | |
michael@0 | 361 | // Destroy any existing panels currently loaded |
michael@0 | 362 | // in the pager. |
michael@0 | 363 | setAdapter(null); |
michael@0 | 364 | |
michael@0 | 365 | // Only keep enabled panels. |
michael@0 | 366 | final List<PanelConfig> enabledPanels = new ArrayList<PanelConfig>(); |
michael@0 | 367 | |
michael@0 | 368 | for (PanelConfig panelConfig : configState) { |
michael@0 | 369 | if (!panelConfig.isDisabled()) { |
michael@0 | 370 | enabledPanels.add(panelConfig); |
michael@0 | 371 | } |
michael@0 | 372 | } |
michael@0 | 373 | |
michael@0 | 374 | // Update the adapter with the new panel configs |
michael@0 | 375 | adapter.update(enabledPanels); |
michael@0 | 376 | |
michael@0 | 377 | final int count = enabledPanels.size(); |
michael@0 | 378 | if (count == 0) { |
michael@0 | 379 | // Set firefox watermark as background. |
michael@0 | 380 | setBackgroundResource(R.drawable.home_pager_empty_state); |
michael@0 | 381 | // Hide the tab strip as there are no panels. |
michael@0 | 382 | mTabStrip.setVisibility(View.INVISIBLE); |
michael@0 | 383 | } else { |
michael@0 | 384 | mTabStrip.setVisibility(View.VISIBLE); |
michael@0 | 385 | // Restore original background. |
michael@0 | 386 | setBackgroundDrawable(mOriginalBackground); |
michael@0 | 387 | } |
michael@0 | 388 | |
michael@0 | 389 | // Re-install the adapter with the final state |
michael@0 | 390 | // in the pager. |
michael@0 | 391 | setAdapter(adapter); |
michael@0 | 392 | |
michael@0 | 393 | if (count == 0) { |
michael@0 | 394 | mDefaultPageIndex = -1; |
michael@0 | 395 | |
michael@0 | 396 | // Hide the banner if there are no enabled panels. |
michael@0 | 397 | if (mHomeBanner != null) { |
michael@0 | 398 | mHomeBanner.setActive(false); |
michael@0 | 399 | } |
michael@0 | 400 | } else { |
michael@0 | 401 | for (int i = 0; i < count; i++) { |
michael@0 | 402 | if (enabledPanels.get(i).isDefault()) { |
michael@0 | 403 | mDefaultPageIndex = i; |
michael@0 | 404 | break; |
michael@0 | 405 | } |
michael@0 | 406 | } |
michael@0 | 407 | |
michael@0 | 408 | // Use the default panel if the initial panel wasn't explicitly set by the |
michael@0 | 409 | // load() caller, or if the initial panel is not found in the adapter. |
michael@0 | 410 | final int itemPosition = (mInitialPanelId == null) ? -1 : adapter.getItemPosition(mInitialPanelId); |
michael@0 | 411 | if (itemPosition > -1) { |
michael@0 | 412 | setCurrentItem(itemPosition, false); |
michael@0 | 413 | mInitialPanelId = null; |
michael@0 | 414 | } else { |
michael@0 | 415 | setCurrentItem(mDefaultPageIndex, false); |
michael@0 | 416 | } |
michael@0 | 417 | } |
michael@0 | 418 | |
michael@0 | 419 | // If the load hint was originally true, this means the pager |
michael@0 | 420 | // is not animating and it's fine to restore the load hint back. |
michael@0 | 421 | if (canLoadHint) { |
michael@0 | 422 | // The selection is updated asynchronously so we need to post to |
michael@0 | 423 | // UI thread to give the pager time to commit the new page selection |
michael@0 | 424 | // internally and load the right initial panel. |
michael@0 | 425 | ThreadUtils.getUiHandler().post(new Runnable() { |
michael@0 | 426 | @Override |
michael@0 | 427 | public void run() { |
michael@0 | 428 | adapter.setCanLoadHint(true); |
michael@0 | 429 | } |
michael@0 | 430 | }); |
michael@0 | 431 | } |
michael@0 | 432 | } |
michael@0 | 433 | |
michael@0 | 434 | public void setOnPanelChangeListener(OnPanelChangeListener listener) { |
michael@0 | 435 | mPanelChangedListener = listener; |
michael@0 | 436 | } |
michael@0 | 437 | |
michael@0 | 438 | /** |
michael@0 | 439 | * Notify listeners of newly selected panel. |
michael@0 | 440 | * |
michael@0 | 441 | * @param position of the newly selected panel |
michael@0 | 442 | */ |
michael@0 | 443 | private void notifyPanelSelected(int position) { |
michael@0 | 444 | if (mDecor != null) { |
michael@0 | 445 | mDecor.onPageSelected(position); |
michael@0 | 446 | } |
michael@0 | 447 | |
michael@0 | 448 | if (mPanelChangedListener != null) { |
michael@0 | 449 | final String panelId = ((HomeAdapter) getAdapter()).getPanelIdAtPosition(position); |
michael@0 | 450 | mPanelChangedListener.onPanelSelected(panelId); |
michael@0 | 451 | } |
michael@0 | 452 | } |
michael@0 | 453 | |
michael@0 | 454 | private class ConfigLoaderCallbacks implements LoaderCallbacks<HomeConfig.State> { |
michael@0 | 455 | @Override |
michael@0 | 456 | public Loader<HomeConfig.State> onCreateLoader(int id, Bundle args) { |
michael@0 | 457 | return new HomeConfigLoader(mContext, mConfig); |
michael@0 | 458 | } |
michael@0 | 459 | |
michael@0 | 460 | @Override |
michael@0 | 461 | public void onLoadFinished(Loader<HomeConfig.State> loader, HomeConfig.State configState) { |
michael@0 | 462 | mLoadState = LoadState.LOADED; |
michael@0 | 463 | updateUiFromConfigState(configState); |
michael@0 | 464 | } |
michael@0 | 465 | |
michael@0 | 466 | @Override |
michael@0 | 467 | public void onLoaderReset(Loader<HomeConfig.State> loader) { |
michael@0 | 468 | mLoadState = LoadState.UNLOADED; |
michael@0 | 469 | } |
michael@0 | 470 | } |
michael@0 | 471 | |
michael@0 | 472 | private class PageChangeListener implements ViewPager.OnPageChangeListener { |
michael@0 | 473 | @Override |
michael@0 | 474 | public void onPageSelected(int position) { |
michael@0 | 475 | notifyPanelSelected(position); |
michael@0 | 476 | |
michael@0 | 477 | if (mHomeBanner != null) { |
michael@0 | 478 | mHomeBanner.setActive(position == mDefaultPageIndex); |
michael@0 | 479 | } |
michael@0 | 480 | |
michael@0 | 481 | // Start a UI telemetry session for the newly selected panel. |
michael@0 | 482 | final String newPanelId = ((HomeAdapter) getAdapter()).getPanelIdAtPosition(position); |
michael@0 | 483 | startNewPanelTelemetrySession(newPanelId); |
michael@0 | 484 | } |
michael@0 | 485 | |
michael@0 | 486 | @Override |
michael@0 | 487 | public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { |
michael@0 | 488 | if (mDecor != null) { |
michael@0 | 489 | mDecor.onPageScrolled(position, positionOffset, positionOffsetPixels); |
michael@0 | 490 | } |
michael@0 | 491 | |
michael@0 | 492 | if (mHomeBanner != null) { |
michael@0 | 493 | mHomeBanner.setScrollingPages(positionOffsetPixels != 0); |
michael@0 | 494 | } |
michael@0 | 495 | } |
michael@0 | 496 | |
michael@0 | 497 | @Override |
michael@0 | 498 | public void onPageScrollStateChanged(int state) { } |
michael@0 | 499 | } |
michael@0 | 500 | |
michael@0 | 501 | /** |
michael@0 | 502 | * Start UI telemetry session for the a panel. |
michael@0 | 503 | * If there is currently a session open for a panel, |
michael@0 | 504 | * it will be stopped before a new one is started. |
michael@0 | 505 | * |
michael@0 | 506 | * @param panelId of panel to start a session for |
michael@0 | 507 | */ |
michael@0 | 508 | private void startNewPanelTelemetrySession(String panelId) { |
michael@0 | 509 | // Stop the current panel's session if we have one. |
michael@0 | 510 | stopCurrentPanelTelemetrySession(); |
michael@0 | 511 | |
michael@0 | 512 | mCurrentPanelSession = TelemetryContract.Session.HOME_PANEL + panelId; |
michael@0 | 513 | Telemetry.startUISession(mCurrentPanelSession); |
michael@0 | 514 | } |
michael@0 | 515 | |
michael@0 | 516 | /** |
michael@0 | 517 | * Stop the current panel telemetry session if one exists. |
michael@0 | 518 | */ |
michael@0 | 519 | private void stopCurrentPanelTelemetrySession() { |
michael@0 | 520 | if (mCurrentPanelSession != null) { |
michael@0 | 521 | Telemetry.stopUISession(mCurrentPanelSession); |
michael@0 | 522 | mCurrentPanelSession = null; |
michael@0 | 523 | } |
michael@0 | 524 | } |
michael@0 | 525 | } |