/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package com.linkbubble.ui;
import android.app.Activity;
import android.app.ActivityManager;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.ActionMode;
import android.view.View;
import android.view.ViewGroup;
import android.webkit.ValueCallback;
import android.widget.FrameLayout;
import android.widget.LinearLayout;
import com.linkbubble.BuildConfig;
import com.linkbubble.Constant;
import com.linkbubble.MainApplication;
import com.linkbubble.MainController;
import com.linkbubble.MainService;
import com.linkbubble.R;
import com.linkbubble.util.CrashTracking;
import com.squareup.otto.Subscribe;
import org.jsoup.helper.StringUtil;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class ExpandedActivity extends Activity {
private static final String TAG = "ExpandedActivity";
private static ExpandedActivity sInstance;
public static ExpandedActivity get() {
return sInstance;
}
public static class MinimizeExpandedActivityEvent {};
public static class ShowFileBrowserEvent {
public ValueCallback<Uri[]> getFilePathCallback() {
return mFilePathCallback;
}
public String[] getAcceptTypes() {
return mAcceptTypes;
}
public ValueCallback<Uri[]> mFilePathCallback;
public String[] mAcceptTypes;
public ShowFileBrowserEvent(String[] acceptTypes, ValueCallback<Uri[]> filePathCallback) {
mFilePathCallback = filePathCallback;
mAcceptTypes = acceptTypes;
}
};
public static class ExpandedActivityReadyEvent {};
private boolean mIsAlive = false;
private boolean mIsShowing = false;
private boolean mRegisteredForBus = false;
private final Handler mHandler = new Handler();
private LinearLayout mWebRendererContainer;
private ValueCallback<Uri[]> mFilePathCallback;
private final static int FILECHOOSER_RESULTCODE = 1;
@Override
protected void onCreate(Bundle savedInstanceState) {
CrashTracking.log("ExpandedActivity.onCreate()");
super.onCreate(savedInstanceState);
// Fixes #454
if (MainController.get() == null || MainController.get().getActiveTabCount() == 0) {
CrashTracking.log("early finish() because nothing to display");
finish();
return;
}
sInstance = this;
mIsAlive = true;
setContentView(R.layout.activity_expanded);
getActionBar().hide();
registerForBus();
FrameLayout rootView = (FrameLayout) findViewById(R.id.expanded_root);
mWebRendererContainer = (LinearLayout) findViewById(R.id.web_renderer_container);
if (Constant.ACTIVITY_WEBVIEW_RENDERING == false) {
//mWebRendererContainer.setWillNotDraw(true);
rootView.removeView(mWebRendererContainer);
mWebRendererContainer = null;
}
if (Constant.EXPANDED_ACTIVITY_DEBUG) {
rootView.setBackgroundColor(0x5500ff00);
} else {
rootView.setWillNotDraw(true);
}
}
@Override
public void onActionModeStarted(ActionMode actionMode) {
super.onActionModeStarted(actionMode);
CrashTracking.log("onActionModeStarted()");
}
@Override
public void onActionModeFinished(ActionMode actionMode) {
super.onActionModeFinished(actionMode);
CrashTracking.log("onActionModeFinished()");
}
/*
* Get the most recent RecentTaskInfo, but ensure the result is not Link Bubble.
*/
ActivityManager.RecentTaskInfo getPreviousTaskInfo(List<ActivityManager.RecentTaskInfo> recentTasks) {
for (int i = 0; i < recentTasks.size(); i++) {
ActivityManager.RecentTaskInfo recentTaskInfo = recentTasks.get(i);
if (recentTaskInfo.baseIntent != null
&& recentTaskInfo.baseIntent.getComponent() != null) {
String packageName = recentTaskInfo.baseIntent.getComponent().getPackageName();
if (packageName.equals("android") == false && packageName.equals(BuildConfig.APPLICATION_ID) == false) {
return recentTaskInfo;
}
}
}
return null;
}
@Override
protected void onDestroy() {
CrashTracking.log("***ExpandedActivity.onDestroy()");
super.onDestroy();
mIsAlive = false;
if (sInstance == this) {
sInstance = null;
}
unregisterForBus();
}
@Override
protected void onStart() {
CrashTracking.log("ExpandedActivity.onStart()");
Log.e(TAG, "Expand time: " + (System.currentTimeMillis() - MainController.sStartExpandedActivityTime));
MainApplication.postEvent(this, new ExpandedActivityReadyEvent());
super.onStart();
}
@Override
protected void onStop() {
CrashTracking.log("ExpandedActivity.onStop()");
super.onStop();
//mTopMaskImage.setVisibility(View.GONE);
//mBottomMaskImage.setVisibility(View.GONE);
}
@Override
public void onResume() {
CrashTracking.log("ExpandedActivity.onResume()");
super.onResume();
mIsShowing = true;
MainController mainController = MainController.get();
if (mainController == null || mainController.contentViewShowing() == false) {
minimize();
}
if (Constant.ACTIVITY_WEBVIEW_RENDERING && mWebRendererContainer.getChildCount() == 0) {
TabView current = MainController.get().getCurrentTab();
if (current != null) {
setWebRenderer(current.getContentView().getWebRenderer().getView());
}
}
}
@Override
public void onPause() {
CrashTracking.log("ExpandedActivity.onPause()");
super.onPause();
mIsShowing = false;
}
@Override
public void finish() {
CrashTracking.log("ExpandedActivity.finish()");
super.finish();
overridePendingTransition(0, 0);
}
@Override
public void onBackPressed() {
delayedMinimize();
}
protected void registerForBus() {
MainApplication.registerForBus(this, this);
mRegisteredForBus = true;
}
protected void unregisterForBus() {
if (mRegisteredForBus) {
MainApplication.unregisterForBus(this, this);
mRegisteredForBus = false;
}
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
// check that the response is a good one
if (requestCode == FILECHOOSER_RESULTCODE) {
Uri[] results = new Uri[0];
if(resultCode==Activity.RESULT_OK) {
if (intent != null) {
String dataString = intent.getDataString();
if (dataString != null) {
results = new Uri[]{Uri.parse(dataString)};
}
}
}
mFilePathCallback.onReceiveValue(results);
mFilePathCallback = null;
MainController.get().switchToExpandedView();
}
}
void minimize() {
if (mIsAlive == false) {
return;
}
// Comment out as a fix for #455
//if (mIsShowing == false) {
// Log.d(TAG, "minimize() - mIsShowing:" + mIsShowing + ", exiting...");
// return;
//}
if (moveTaskToBack(true)) {
CrashTracking.log("minimize() - moveTaskToBack(true);");
return;
}
if (MainController.get() != null) {
MainController.get().showBadge(true);
}
final ActivityManager activityManager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
List<ActivityManager.RecentTaskInfo> recentTasks = activityManager.getRecentTasks(16, ActivityManager.RECENT_WITH_EXCLUDED);
if (recentTasks.size() > 0) {
ActivityManager.RecentTaskInfo recentTaskInfo = getPreviousTaskInfo(recentTasks);
ComponentName componentName = recentTaskInfo.baseIntent.getComponent();
//openedFromAppName = componentName.getPackageName();
Intent intent = new Intent();
intent.setComponent(componentName);
intent.setFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
startActivity(intent);
overridePendingTransition(0, 0);
CrashTracking.log("minimize() - " + componentName);
} else {
CrashTracking.log("minimize() - NONE!");
}
}
void showFileBrowser(final String[] acceptTypes, ValueCallback<Uri[]> filePathCallback) {
MainController.get().switchToBubbleView(false);
mFilePathCallback = filePathCallback;
Runnable runnable = new Runnable() {
@Override
public void run() {
mHandler.post(new Runnable() {
@Override
public void run() {
Intent i = new Intent(Intent.ACTION_GET_CONTENT);
i.addCategory(Intent.CATEGORY_OPENABLE);
// Android intents wants mime types, filepickers can specify
// mime types or file types, filter out the file types.
ArrayList<String> filteredList = new ArrayList<>();
for (String acceptType : acceptTypes) {
if (acceptType.contains("/")) {
filteredList.add(acceptType);
}
}
if (filteredList.size() == 0) {
i.setType("*/*");
} else {
i.setType(StringUtil.join(filteredList, ","));
}
startActivityForResult(Intent.createChooser(i, "File Chooser"), FILECHOOSER_RESULTCODE);
}
});
}
};
new Thread(runnable).start();
}
void delayedMinimize() {
// Kill the activity to ensure it is not alive in the event a link is intercepted,
// thus displaying the ugly UI for a few frames
//fadeOut();
mHandler.postDelayed(mMinimizeRunnable, 500);
}
void cancelDelayedMinimize() {
//fadeIn();
mHandler.removeCallbacks(mMinimizeRunnable);
}
private Runnable mMinimizeRunnable = new Runnable() {
@Override
public void run() {
minimize();
}
};
public void setWebRenderer(View view) {
if (mWebRendererContainer.getChildCount() == 0) {
if (view.getParent() != null) {
((ViewGroup) view.getParent()).removeView(view);
}
mWebRendererContainer.addView(view);
}
}
@SuppressWarnings("unused")
@Subscribe
public void onMinimizeExpandedActivity(MinimizeExpandedActivityEvent e) {
minimize();
}
@SuppressWarnings("unused")
@Subscribe
public void onShowFileBrowserEvent(ShowFileBrowserEvent e) {
showFileBrowser(e.getAcceptTypes(), e.getFilePathCallback());
}
@SuppressWarnings("unused")
@Subscribe
public void onHideContentEvent(MainController.HideContentEvent event) {
finish();
}
@SuppressWarnings("unused")
@Subscribe
public void OnOnDestroyMainServiceEvent(MainService.OnDestroyMainServiceEvent event) {
finish();
}
}