Contents
Activities
LaunchActivity
The app starts by launching LaunchActivity.
This activity merely starts an instance of SplashActivity.
SplashActivity
onCreate(...)
The app first configures a VM-wide cookie manager to synchronize cookies between the HTTP requests and the WebViews.
App.setCookieManager(new CookieManager()); CookieHandler.setDefault(App.getCookieManager());
Then, getGlobalConfig() is called.
getGlobalConfig()
If the global config boolean is set to true, then the app will pull down the global configuration that matches the version number associated with the app.
If the global config is properly attained, the function checks if an upgrade is needed or required. If it is, the proper dialog box will be shown. If it is not, then the account feed will be pulled down.
getAccountFeed()
This function first checks if the user has an account or not.
If they do, log them in using the LoginActivity. If they don't, make sure the cookies aren't stale and pull down the layout feed.
In the onSuccess(...) response of the callback, the JSON acquired from restApi.getMainFeed(...) will be parsed into a Layout object by way of the LayoutDeserializer.
If global config is turned on, the app will filter portlets out of the list that are not supposed to show on the mobile app (e.g. the advertisement for the mobile app).
The HomePageActivity is then called.
HomePageActivity
The HomePageActivity houses the HomePageListFragment, which does most of the work displaying the content.
However, the HomePageActivity has the important role of managing the fragments.
setUpNavigationDrawer()
During setUpNavigationDrawer(), the folders to be listed in the navigation drawer are gathered from the layoutManager and adapted with FolderListAdapter.
The last line in the function is selectItem(...), which manages the fragment to be selected.
selectItem(...)
The important lines here are:
Bundle args = new Bundle(); args.putInt(AppConstants.POSITION, position); Fragment fragment = HomePageListFragment.getFragment(this); fragment.setArguments(args); getFragmentManager() .beginTransaction() .replace(R.id.content_frame, fragment) .commit();
selectItem(...) is triggered when a user requests to switch folders (tabs) from the navigation drawer. This replaces the current fragment (folder / tab) in view with whatever new one is selected.
launchWebView(...)
This merely sends the application to the PortletWebViewActivity with extra arguments attached.
PortletWebViewActivity
initialize()
The navigation drawer setup is called here.
The webView.setWebViewClient(...) uses a new WebViewClient which implements the onPageFinished(...) function. Our implementation checks if the WebView is loading the CAS login page or not. If it is, attempt to log the user back in and ship them back to the WebView. Else, start the app over.
The webView.setWebChromeClient(...) uses a new WebViewChromeClient which implements the onProgressChanged(...) method. This basically just sets the progress bar to how much the page has loaded and hides it when the loading is done.
The webView.setDownloadListener(...) uses a new DownloadListener which implements the onDownloadStart(...) method. In this method, we set the cookie to the cookie acquired for the domain and make Android's notification system listen for the download progress and completion.
Fragments
HomePageListFragment
There is a global list that represents the ListView in the layout.
This ListView is populated by an adapter.
The header and status bar are manipulated to be pretty.
initialize()
This attaches the header image to the ListView for parallaxing.
It is set for each item in the list to launch a WebView on click by way of the list.setOnItemClickListener(...).
Also, the ListView has a scroll listener attached for parallaxing.
fetchLayout()
The PortletListAdapter sets up the list that is the portlets displayed in each folder.
onScrollListener
This scroll listener parallaxes the header and changes the color of the action and status bar.
Deserializers
The deserializers in this app look through the JSON received, parse the correct information from the feed, and build a Java object to represent the information.
ConfigDeserializer
This looks through the global config JSON and gathers:
- Whether upgrade to app is recommended
- Whether upgrade to app is required
- Which portlets are to be excluded from the layout
LayoutDeserializer
This looks through the layout JSON and gathers:
- The folder layout
- The portlets for each layout
Services
RestApi
The root URL is set here. Pay attention to how the callbackHandler reacts to the inputs in the functions.
getMainFeed(...)
This function attempts to grab the layout.json file from uPortal. It sends the JSESSIONID cookie with the request to pull down the feed.
getGlobalConfig(...)
This function attempts to grab the global config JSON file based on the app's version.
RestInterface
getMainFeed()
Using the root URL set in the RestApi, this function sends a GET request to the root URL + the @Get annotation's parameter.
getGlobalConfig(...)
Using the root URL set in the RestApi, this function sends a GET request to the root URL + the @Get annotation's parameter with the Java function's parameter included in curly braces.
Utils
CasClient
authenticate(...)
This is the initializer to log in to CAS.
postForServiceTicketLocation(...)
This function sends a post to the CAS ticket API with username and password encoded as parameters. The ticket granting ticket (TGT) is gathered from response.
postForServiceTicket()
Using the TGT, this function sends a request to the login service and returns the service ticket (ST).
validateServiceTicket(...)
This function sends a request to the uPortal login service. The app collects the and sets the CAS cookie and the uPortal cookie (JSESSIONID).