/*
* Copyright 2012 Google Inc.
*
* 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.iosched.ui.tablet;
import com.google.analytics.tracking.android.EasyTracker;
import com.google.android.apps.iosched.R;
import com.google.android.apps.iosched.provider.ScheduleContract;
import com.google.android.apps.iosched.ui.BaseActivity;
import com.google.android.apps.iosched.ui.SessionDetailFragment;
import com.google.android.apps.iosched.ui.SessionsFragment;
import com.google.android.apps.iosched.ui.TrackInfoHelperFragment;
import com.google.android.apps.iosched.ui.VendorDetailFragment;
import com.google.android.apps.iosched.ui.VendorsFragment;
import com.google.android.apps.iosched.ui.widget.ShowHideMasterLayout;
import com.google.android.apps.iosched.util.BeamUtils;
import com.google.android.apps.iosched.util.UIUtils;
import com.actionbarsherlock.app.ActionBar;
import com.actionbarsherlock.view.Menu;
import com.actionbarsherlock.view.MenuItem;
import android.annotation.TargetApi;
import android.app.AlertDialog;
import android.app.SearchManager;
import android.content.DialogInterface;
import android.content.Intent;
import android.net.Uri;
import android.nfc.NfcAdapter;
import android.nfc.NfcEvent;
import android.os.Build;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.widget.SearchView;
import static com.google.android.apps.iosched.util.LogUtils.LOGD;
/**
* A multi-pane activity, consisting of a {@link TracksDropdownFragment} (top-left), a
* {@link SessionsFragment} or {@link VendorsFragment} (bottom-left), and
* a {@link SessionDetailFragment} or {@link VendorDetailFragment} (right pane).
*/
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
public class SessionsVendorsMultiPaneActivity extends BaseActivity implements
ActionBar.TabListener,
SessionsFragment.Callbacks,
VendorsFragment.Callbacks,
VendorDetailFragment.Callbacks,
TracksDropdownFragment.Callbacks,
TrackInfoHelperFragment.Callbacks {
public static final String EXTRA_MASTER_URI =
"com.google.android.apps.iosched.extra.MASTER_URI";
private static final String STATE_VIEW_TYPE = "view_type";
private TracksDropdownFragment mTracksDropdownFragment;
private Fragment mDetailFragment;
private boolean mFullUI = false;
private ShowHideMasterLayout mShowHideMasterLayout;
private String mViewType;
private boolean mInitialTabSelect = true;
@Override
protected void onCreate(Bundle savedInstanceState) {
if (BeamUtils.wasLaunchedThroughBeamFirstTime(this, getIntent())) {
BeamUtils.setBeamUnlocked(this);
showFirstBeamDialog();
}
BeamUtils.tryUpdateIntentFromBeam(this);
super.onCreate(savedInstanceState);
trySetBeamCallback();
setContentView(R.layout.activity_sessions_vendors);
final FragmentManager fm = getSupportFragmentManager();
mTracksDropdownFragment = (TracksDropdownFragment) fm.findFragmentById(
R.id.fragment_tracks_dropdown);
mShowHideMasterLayout = (ShowHideMasterLayout) findViewById(R.id.show_hide_master_layout);
if (mShowHideMasterLayout != null) {
mShowHideMasterLayout.setFlingToExposeMasterEnabled(true);
}
routeIntent(getIntent(), savedInstanceState != null);
if (savedInstanceState != null) {
if (mFullUI) {
getSupportActionBar().setSelectedNavigationItem(
TracksDropdownFragment.VIEW_TYPE_SESSIONS.equals(
savedInstanceState.getString(STATE_VIEW_TYPE)) ? 0 : 1);
}
mDetailFragment = fm.findFragmentById(R.id.fragment_container_detail);
updateDetailBackground();
}
// This flag prevents onTabSelected from triggering extra master pane reloads
// unless it's actually being triggered by the user (and not automatically by
// the system)
mInitialTabSelect = false;
EasyTracker.getTracker().setContext(this);
}
private void routeIntent(Intent intent, boolean updateSurfaceOnly) {
Uri uri = intent.getData();
if (uri == null) {
return;
}
if (intent.hasExtra(Intent.EXTRA_TITLE)) {
setTitle(intent.getStringExtra(Intent.EXTRA_TITLE));
}
String mimeType = getContentResolver().getType(uri);
if (ScheduleContract.Tracks.CONTENT_ITEM_TYPE.equals(mimeType)) {
// Load track details
showFullUI(true);
if (!updateSurfaceOnly) {
// TODO: don't assume the URI will contain the track ID
String selectedTrackId = ScheduleContract.Tracks.getTrackId(uri);
loadTrackList(TracksDropdownFragment.VIEW_TYPE_SESSIONS, selectedTrackId);
onTrackSelected(selectedTrackId);
if (mShowHideMasterLayout != null) {
mShowHideMasterLayout.showMaster(true, ShowHideMasterLayout.FLAG_IMMEDIATE);
}
}
} else if (ScheduleContract.Sessions.CONTENT_TYPE.equals(mimeType)) {
// Load a session list, hiding the tracks dropdown and the tabs
mViewType = TracksDropdownFragment.VIEW_TYPE_SESSIONS;
showFullUI(false);
if (!updateSurfaceOnly) {
loadSessionList(uri, null);
if (mShowHideMasterLayout != null) {
mShowHideMasterLayout.showMaster(true, ShowHideMasterLayout.FLAG_IMMEDIATE);
}
}
} else if (ScheduleContract.Sessions.CONTENT_ITEM_TYPE.equals(mimeType)) {
// Load session details
if (intent.hasExtra(EXTRA_MASTER_URI)) {
mViewType = TracksDropdownFragment.VIEW_TYPE_SESSIONS;
showFullUI(false);
if (!updateSurfaceOnly) {
loadSessionList((Uri) intent.getParcelableExtra(EXTRA_MASTER_URI),
ScheduleContract.Sessions.getSessionId(uri));
loadSessionDetail(uri);
}
} else {
mViewType = TracksDropdownFragment.VIEW_TYPE_SESSIONS; // prepare for onTrackInfo...
showFullUI(true);
if (!updateSurfaceOnly) {
loadSessionDetail(uri);
loadTrackInfoFromSessionUri(uri);
}
}
} else if (ScheduleContract.Vendors.CONTENT_TYPE.equals(mimeType)) {
// Load a vendor list
mViewType = TracksDropdownFragment.VIEW_TYPE_VENDORS;
showFullUI(false);
if (!updateSurfaceOnly) {
loadVendorList(uri, null);
if (mShowHideMasterLayout != null) {
mShowHideMasterLayout.showMaster(true, ShowHideMasterLayout.FLAG_IMMEDIATE);
}
}
} else if (ScheduleContract.Vendors.CONTENT_ITEM_TYPE.equals(mimeType)) {
// Load vendor details
mViewType = TracksDropdownFragment.VIEW_TYPE_VENDORS;
showFullUI(false);
if (!updateSurfaceOnly) {
Uri masterUri = (Uri) intent.getParcelableExtra(EXTRA_MASTER_URI);
if (masterUri == null) {
masterUri = ScheduleContract.Vendors.CONTENT_URI;
}
loadVendorList(masterUri, ScheduleContract.Vendors.getVendorId(uri));
loadVendorDetail(uri);
}
}
updateDetailBackground();
}
private void showFullUI(boolean fullUI) {
mFullUI = fullUI;
final ActionBar actionBar = getSupportActionBar();
final FragmentManager fm = getSupportFragmentManager();
if (fullUI) {
actionBar.removeAllTabs();
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
actionBar.setDisplayShowTitleEnabled(false);
actionBar.addTab(actionBar.newTab()
.setText(R.string.title_sessions)
.setTag(TracksDropdownFragment.VIEW_TYPE_SESSIONS)
.setTabListener(this));
actionBar.addTab(actionBar.newTab()
.setText(R.string.title_vendors)
.setTag(TracksDropdownFragment.VIEW_TYPE_VENDORS)
.setTabListener(this));
fm.beginTransaction()
.show(fm.findFragmentById(R.id.fragment_tracks_dropdown))
.commit();
} else {
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD);
actionBar.setDisplayShowTitleEnabled(true);
fm.beginTransaction()
.hide(fm.findFragmentById(R.id.fragment_tracks_dropdown))
.commit();
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
getSupportMenuInflater().inflate(R.menu.search, menu);
MenuItem searchItem = menu.findItem(R.id.menu_search);
if (searchItem != null && UIUtils.hasHoneycomb()) {
SearchView searchView = (SearchView) searchItem.getActionView();
if (searchView != null) {
SearchManager searchManager = (SearchManager) getSystemService(SEARCH_SERVICE);
searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName()));
}
}
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
int itemId = item.getItemId();
if (itemId == android.R.id.home) {
if (mShowHideMasterLayout != null && !mShowHideMasterLayout.isMasterVisible()) {
// If showing the detail view, pressing Up should show the master pane.
mShowHideMasterLayout.showMaster(true, 0);
return true;
}
} else if (itemId == R.id.menu_search) {
if (!UIUtils.hasHoneycomb()) {
startSearch(null, false, Bundle.EMPTY, false);
return true;
}
}
return super.onOptionsItemSelected(item);
}
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putString(STATE_VIEW_TYPE, mViewType);
}
@Override
public void onTabSelected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {
loadTrackList((String) tab.getTag());
if (!mInitialTabSelect) {
onTrackSelected(mTracksDropdownFragment.getSelectedTrackId());
if (mShowHideMasterLayout != null) {
mShowHideMasterLayout.showMaster(true, 0);
}
}
}
@Override
public void onTabUnselected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {
}
@Override
public void onTabReselected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {
}
private void loadTrackList(String viewType) {
loadTrackList(viewType, null);
}
private void loadTrackList(String viewType, String selectTrackId) {
if (mDetailFragment != null && !mViewType.equals(viewType)) {
getSupportFragmentManager().beginTransaction()
.remove(mDetailFragment)
.commit();
mDetailFragment = null;
}
mViewType = viewType;
if (selectTrackId != null) {
mTracksDropdownFragment.loadTrackList(viewType, selectTrackId);
} else {
mTracksDropdownFragment.loadTrackList(viewType);
}
updateDetailBackground();
}
private void updateDetailBackground() {
if (mDetailFragment == null) {
if (TracksDropdownFragment.VIEW_TYPE_SESSIONS.equals(mViewType)) {
findViewById(R.id.fragment_container_detail).setBackgroundResource(
R.drawable.grey_frame_on_white_empty_sessions);
} else {
findViewById(R.id.fragment_container_detail).setBackgroundResource(
R.drawable.grey_frame_on_white_empty_sandbox);
}
} else {
findViewById(R.id.fragment_container_detail).setBackgroundResource(
R.drawable.grey_frame_on_white);
}
}
private void loadSessionList(Uri sessionsUri, String selectSessionId) {
SessionsFragment fragment = new SessionsFragment();
fragment.setSelectedSessionId(selectSessionId);
fragment.setArguments(BaseActivity.intentToFragmentArguments(
new Intent(Intent.ACTION_VIEW, sessionsUri)));
getSupportFragmentManager().beginTransaction()
.replace(R.id.fragment_container_master, fragment)
.commit();
}
private void loadSessionDetail(Uri sessionUri) {
BeamUtils.setBeamSessionUri(this, sessionUri);
SessionDetailFragment fragment = new SessionDetailFragment();
fragment.setArguments(BaseActivity.intentToFragmentArguments(
new Intent(Intent.ACTION_VIEW, sessionUri)));
getSupportFragmentManager().beginTransaction()
.replace(R.id.fragment_container_detail, fragment)
.commit();
mDetailFragment = fragment;
updateDetailBackground();
// If loading session details in portrait, hide the master pane
if (mShowHideMasterLayout != null) {
mShowHideMasterLayout.showMaster(false, 0);
}
}
private void loadVendorList(Uri vendorsUri, String selectVendorId) {
VendorsFragment fragment = new VendorsFragment();
fragment.setSelectedVendorId(selectVendorId);
fragment.setArguments(BaseActivity.intentToFragmentArguments(
new Intent(Intent.ACTION_VIEW, vendorsUri)));
getSupportFragmentManager().beginTransaction()
.replace(R.id.fragment_container_master, fragment)
.commit();
}
private void loadVendorDetail(Uri vendorUri) {
VendorDetailFragment fragment = new VendorDetailFragment();
fragment.setArguments(BaseActivity.intentToFragmentArguments(
new Intent(Intent.ACTION_VIEW, vendorUri)));
getSupportFragmentManager().beginTransaction()
.replace(R.id.fragment_container_detail, fragment)
.commit();
mDetailFragment = fragment;
updateDetailBackground();
// If loading session details in portrait, hide the master pane
if (mShowHideMasterLayout != null) {
mShowHideMasterLayout.showMaster(false, 0);
}
}
@Override
public void onTrackNameAvailable(String trackId, String trackName) {
String trackType;
if (TracksDropdownFragment.VIEW_TYPE_SESSIONS.equals(mViewType)) {
trackType = getString(R.string.title_sessions);
} else {
trackType = getString(R.string.title_vendors);
}
EasyTracker.getTracker().trackView(trackType + ": " + getTitle());
LOGD("Tracker", trackType + ": " + mTracksDropdownFragment.getTrackName());
}
@Override
public void onTrackSelected(String trackId) {
boolean allTracks = (ScheduleContract.Tracks.ALL_TRACK_ID.equals(trackId));
if (TracksDropdownFragment.VIEW_TYPE_SESSIONS.equals(mViewType)) {
loadSessionList(allTracks
? ScheduleContract.Sessions.CONTENT_URI
: ScheduleContract.Tracks.buildSessionsUri(trackId), null);
} else {
loadVendorList(allTracks
? ScheduleContract.Vendors.CONTENT_URI
: ScheduleContract.Tracks.buildVendorsUri(trackId), null);
}
}
@Override
public boolean onSessionSelected(String sessionId) {
loadSessionDetail(ScheduleContract.Sessions.buildSessionUri(sessionId));
return true;
}
@Override
public boolean onVendorSelected(String vendorId) {
loadVendorDetail(ScheduleContract.Vendors.buildVendorUri(vendorId));
return true;
}
private TrackInfoHelperFragment mTrackInfoHelperFragment;
private String mTrackInfoLoadCookie;
private void loadTrackInfoFromSessionUri(Uri sessionUri) {
mTrackInfoLoadCookie = ScheduleContract.Sessions.getSessionId(sessionUri);
Uri trackDirUri = ScheduleContract.Sessions.buildTracksDirUri(
ScheduleContract.Sessions.getSessionId(sessionUri));
android.support.v4.app.FragmentTransaction ft =
getSupportFragmentManager().beginTransaction();
if (mTrackInfoHelperFragment != null) {
ft.remove(mTrackInfoHelperFragment);
}
mTrackInfoHelperFragment = TrackInfoHelperFragment.newFromTrackUri(trackDirUri);
ft.add(mTrackInfoHelperFragment, "track_info").commit();
}
@Override
public void onTrackInfoAvailable(String trackId, String trackName, int trackColor) {
loadTrackList(mViewType, trackId);
boolean allTracks = (ScheduleContract.Tracks.ALL_TRACK_ID.equals(trackId));
if (TracksDropdownFragment.VIEW_TYPE_SESSIONS.equals(mViewType)) {
loadSessionList(allTracks
? ScheduleContract.Sessions.CONTENT_URI
: ScheduleContract.Tracks.buildSessionsUri(trackId),
mTrackInfoLoadCookie);
} else {
loadVendorList(allTracks
? ScheduleContract.Vendors.CONTENT_URI
: ScheduleContract.Tracks.buildVendorsUri(trackId),
mTrackInfoLoadCookie);
}
}
@Override
public void onTrackIdAvailable(String trackId) {
}
@TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH)
private void trySetBeamCallback() {
if (UIUtils.hasICS()) {
BeamUtils.setBeamCompleteCallback(this, new NfcAdapter.OnNdefPushCompleteCallback() {
@Override
public void onNdefPushComplete(NfcEvent event) {
// Beam has been sent
if (!BeamUtils.isBeamUnlocked(SessionsVendorsMultiPaneActivity.this)) {
BeamUtils.setBeamUnlocked(SessionsVendorsMultiPaneActivity.this);
runOnUiThread(new Runnable() {
@Override
public void run() {
showFirstBeamDialog();
}
});
}
}
});
}
}
private void showFirstBeamDialog() {
new AlertDialog.Builder(this)
.setTitle(R.string.just_beamed)
.setMessage(R.string.beam_unlocked_session)
.setNegativeButton(R.string.close, null)
.setPositiveButton(R.string.view_beam_session,
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface di, int i) {
BeamUtils.launchBeamSession(SessionsVendorsMultiPaneActivity.this);
di.dismiss();
}
})
.create()
.show();
}
}