package android.support.v4.app;
import android.annotation.SuppressLint;
import android.content.ActivityNotFoundException;
import android.content.Context;
import android.content.ContextWrapper;
import android.content.Intent;
import android.content.res.Resources.Theme;
import android.content.res.TypedArray;
import android.graphics.Rect;
import android.os.Build.VERSION;
import android.os.Bundle;
import android.os.Handler;
import android.os.Parcel;
import android.os.Parcelable;
import android.support.v7.app.ActionBarActivity;
import android.support.v7.internal.view.menu.ContextMenuCallbackGetter;
import android.support.v7.internal.view.menu.ContextMenuDecorView.ContextMenuListenersProvider;
import android.support.v7.internal.view.menu.ContextMenuListener;
import android.test.mock.MockApplication;
import android.util.Log;
import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.View;
import android.view.View.OnCreateContextMenuListener;
import android.view.ViewGroup;
import android.view.ViewGroup.LayoutParams;
import android.view.Window;
import org.holoeverywhere.HoloEverywhere;
import org.holoeverywhere.HoloEverywhere.PreferenceImpl;
import org.holoeverywhere.LayoutInflater;
import org.holoeverywhere.R;
import org.holoeverywhere.SystemServiceManager;
import org.holoeverywhere.SystemServiceManager.SuperSystemService;
import org.holoeverywhere.ThemeManager;
import org.holoeverywhere.ThemeManager.SuperStartActivity;
import org.holoeverywhere.addon.IAddonActivity;
import org.holoeverywhere.addon.IAddonAttacher;
import org.holoeverywhere.app.Activity;
import org.holoeverywhere.app.Application;
import org.holoeverywhere.app.ContextThemeWrapperPlus;
import org.holoeverywhere.preference.PreferenceManagerHelper;
import org.holoeverywhere.preference.SharedPreferences;
import org.holoeverywhere.util.SparseIntArray;
import org.holoeverywhere.util.WeaklyMap;
import org.holoeverywhere.widget.WindowDecorView;
import java.util.Map;
public abstract class _HoloActivity extends ActionBarActivity implements SuperStartActivity,
SuperSystemService, ContextMenuListener,
ContextMenuListenersProvider, IAddonAttacher<IAddonActivity> {
private static final String CONFIG_KEY = "holo:config:activity";
private Context mActionBarContext;
private Holo mConfig;
private Map<View, ContextMenuListener> mContextMenuListeners;
private WindowDecorView mDecorView;
private boolean mInited = false;
private int mLastThemeResourceId = 0;
private Handler mUserHandler;
public static FragmentActivity extract(Context context, boolean exceptionWhenNotFound) {
FragmentActivity fa = null;
while (context instanceof ContextWrapper) {
if (context instanceof FragmentActivity) {
fa = (FragmentActivity) context;
break;
}
context = ((ContextWrapper) context).getBaseContext();
}
if (fa == null && exceptionWhenNotFound) {
throw new ActivityNotFoundException();
}
return fa;
}
@Override
public void addContentView(View view, LayoutParams params) {
if (requestDecorView(view, params, -1)) {
mDecorView.addView(view, params);
}
onSupportContentChanged();
}
protected Holo createConfig(Bundle savedInstanceState) {
if (mConfig == null) {
mConfig = onCreateConfig(savedInstanceState);
}
if (mConfig == null) {
mConfig = Holo.defaultConfig();
}
return mConfig;
}
protected void forceInit(Bundle savedInstanceState) {
if (mInited) {
return;
}
if (mConfig == null && savedInstanceState != null
&& savedInstanceState.containsKey(CONFIG_KEY)) {
mConfig = savedInstanceState.getParcelable(CONFIG_KEY);
}
onInit(mConfig, savedInstanceState);
}
public Holo getConfig() {
return mConfig;
}
@Override
public ContextMenuListener getContextMenuListener(View view) {
if (mContextMenuListeners == null) {
return null;
}
return mContextMenuListeners.get(view);
}
public SharedPreferences getDefaultSharedPreferences() {
return PreferenceManagerHelper.getDefaultSharedPreferences(this);
}
public SharedPreferences getDefaultSharedPreferences(PreferenceImpl impl) {
return PreferenceManagerHelper.getDefaultSharedPreferences(this, impl);
}
public int getLastThemeResourceId() {
return mLastThemeResourceId;
}
@Override
public LayoutInflater getLayoutInflater() {
return LayoutInflater.from(this);
}
public SharedPreferences getSharedPreferences(PreferenceImpl impl,
String name, int mode) {
return PreferenceManagerHelper.wrap(this, impl, name, mode);
}
@Override
public SharedPreferences getSharedPreferences(String name, int mode) {
return PreferenceManagerHelper.wrap(this, name, mode);
}
/**
* @return Themed context for using in action bar
*/
public Context getSupportActionBarContext() {
if (mActionBarContext == null) {
int theme = ThemeManager.getThemeType(this);
if (theme != ThemeManager.LIGHT) {
theme = ThemeManager.DARK;
}
theme = ThemeManager.getThemeResource(theme, false);
if (mLastThemeResourceId == theme) {
mActionBarContext = this;
} else {
mActionBarContext = new ContextThemeWrapperPlus(this, theme);
}
}
return mActionBarContext;
}
public Application getSupportApplication() {
return Application.getLastInstance();
}
@Override
public Object getSystemService(String name) {
return SystemServiceManager.getSystemService(this, name);
}
@Override
public Theme getTheme() {
if (mLastThemeResourceId == 0) {
setTheme(ThemeManager.getDefaultTheme());
}
return super.getTheme();
}
@Override
public void setTheme(int resid) {
setTheme(resid, true);
}
public LayoutInflater getThemedLayoutInflater() {
return getLayoutInflater();
}
public Handler getUserHandler() {
if (mUserHandler == null) {
mUserHandler = new Handler(getMainLooper());
}
return mUserHandler;
}
protected final WindowDecorView getWindowDecorView() {
return mDecorView;
}
public boolean isDecorViewInited() {
return mDecorView != null;
}
public boolean isInited() {
return mInited;
}
@Override
protected void onCreate(Bundle savedInstanceState) {
forceInit(savedInstanceState);
super.onCreate(savedInstanceState);
if (this instanceof Activity && mConfig != null) {
mConfig.requestWindowFeature((Activity) this);
}
}
protected Holo onCreateConfig(Bundle savedInstanceState) {
if (savedInstanceState != null && savedInstanceState.containsKey(CONFIG_KEY)) {
final Holo config = savedInstanceState.getParcelable(CONFIG_KEY);
if (config != null) {
return config;
}
}
return Holo.defaultConfig();
}
@Override
public void onCreateContextMenu(ContextMenu menu, View view, ContextMenuInfo menuInfo) {
super.onCreateContextMenu(menu, view, menuInfo);
if (view instanceof ContextMenuCallbackGetter) {
final OnCreateContextMenuListener l = ((ContextMenuCallbackGetter) view)
.getOnCreateContextMenuListener();
if (l != null) {
l.onCreateContextMenu(menu, view, menuInfo);
}
}
}
@Override
protected void onDestroy() {
super.onDestroy();
LayoutInflater.removeInstance(this);
}
/**
* Do not override this method. Use {@link #onPreInit(Holo, Bundle)} and
* {@link #onPostInit(Holo, Bundle)}
*/
protected void onInit(Holo config, Bundle savedInstanceState) {
if (mInited) {
throw new IllegalStateException("This instance was already inited");
}
mInited = true;
if (config == null) {
config = createConfig(savedInstanceState);
}
if (config == null) {
config = Holo.defaultConfig();
}
onPreInit(config, savedInstanceState);
if (!config.ignoreApplicationInstanceCheck && !(getApplication() instanceof Application)) {
boolean throwError = true;
if (config.allowMockApplicationInstance) {
try {
throwError = !(getApplication() instanceof MockApplication);
if (!throwError) {
Log.w("HoloEverywhere", "Application instance is MockApplication. Wow. Let's begin tests...");
}
} catch (Exception e) {
}
}
if (throwError) {
String text = "Application instance isn't HoloEverywhere.\n";
if (getApplication().getClass() == android.app.Application.class) {
text += "Put attr 'android:name=\"org.holoeverywhere.app.Application\"'" +
" in <application> tag of AndroidManifest.xml";
} else {
text += "Please sure that you extend " + getApplication().getClass() +
" from a org.holoeverywhere.app.Application";
}
throw new IllegalStateException(text);
}
}
getLayoutInflater().setFragmentActivity(this);
if (this instanceof Activity) {
final Activity activity = (Activity) this;
ThemeManager.applyTheme(activity, mLastThemeResourceId == 0);
if (!config.ignoreThemeCheck && ThemeManager.getThemeType(this) == ThemeManager.INVALID) {
throw new HoloThemeException(activity);
}
TypedArray a = obtainStyledAttributes(new int[]{android.R.attr.windowActionBarOverlay, R.attr.windowActionBarOverlay});
if (a.getBoolean(0, false) || a.getBoolean(1, false)) {
supportRequestWindowFeature(Window.FEATURE_ACTION_BAR_OVERLAY);
}
a.recycle();
a = obtainStyledAttributes(new int[]{android.R.attr.windowActionModeOverlay, R.attr.windowActionBarOverlay});
if (a.getBoolean(0, false) || a.getBoolean(1, false)) {
supportRequestWindowFeature(Window.FEATURE_ACTION_MODE_OVERLAY);
}
a.recycle();
}
onPostInit(config, savedInstanceState);
lockAttaching();
}
@Override
protected void onPostCreate(Bundle savedInstanceState) {
requestDecorView(null, null, -1);
super.onPostCreate(savedInstanceState);
}
protected void onPostInit(Holo config, Bundle savedInstanceState) {
}
protected void onPreInit(Holo config, Bundle savedInstanceState) {
}
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
if (mConfig != null) {
outState.putParcelable(CONFIG_KEY, mConfig);
}
}
@Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
if (mDecorView != null) {
rOnWindowFocusChanged(mDecorView, hasFocus);
}
}
private void rOnWindowFocusChanged(View view, boolean hasFocus) {
if (view instanceof OnWindowFocusChangeListener) {
((OnWindowFocusChangeListener) view).onWindowFocusChanged(hasFocus);
}
if (view instanceof ViewGroup) {
final ViewGroup vg = (ViewGroup) view;
final int childCount = vg.getChildCount();
for (int i = 0; i < childCount; i++) {
rOnWindowFocusChanged(vg.getChildAt(i), hasFocus);
}
}
}
@Override
public void registerForContextMenu(View view) {
registerForContextMenu(view, this);
}
public void registerForContextMenu(View view, ContextMenuListener listener) {
if (mContextMenuListeners == null) {
mContextMenuListeners = new WeaklyMap<View, ContextMenuListener>();
}
mContextMenuListeners.put(view, listener);
view.setLongClickable(true);
}
protected final void requestDecorView() {
if (mDecorView == null) {
requestDecorView(null, null, -1);
}
}
private boolean requestDecorView(View view, LayoutParams params, int layoutRes) {
if (mDecorView != null) {
return true;
}
mDecorView = new ActivityDecorView();
mDecorView.setId(android.R.id.content);
mDecorView.setProvider(this);
if (view != null) {
mDecorView.addView(view, params);
} else if (layoutRes > 0) {
getThemedLayoutInflater().inflate(layoutRes, mDecorView, true);
}
final LayoutParams p = new LayoutParams(
LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
performAddonAction(new AddonCallback<IAddonActivity>() {
@Override
public boolean action(IAddonActivity addon) {
return addon.installDecorView(mDecorView, p);
}
@Override
public void justPost() {
_HoloActivity.super.setContentView(mDecorView, p);
}
});
return false;
}
/**
* @deprecated Use @{link supportRequestWindowFeature(int)} instead
*/
public void requestWindowFeature(long featureId) {
supportRequestWindowFeature((int) featureId);
}
@Override
public boolean supportRequestWindowFeature(int featureId) {
createConfig(null).requestWindowFeature(featureId);
return !isSupportImplReady() || super.supportRequestWindowFeature(featureId);
}
@Override
public void setContentView(int layoutResID) {
if (requestDecorView(null, null, layoutResID)) {
mDecorView.removeAllViewsInLayout();
getThemedLayoutInflater().inflate(layoutResID, mDecorView, true);
}
onSupportContentChanged();
}
public void onSupportContentChanged() {
}
@Override
public void setContentView(View view) {
setContentView(view, new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
}
@Override
public void setContentView(View view, LayoutParams params) {
if (requestDecorView(view, params, -1)) {
mDecorView.removeAllViewsInLayout();
mDecorView.addView(view, params);
}
onSupportContentChanged();
}
public synchronized void setTheme(int resid, boolean modifyGlobal) {
if (resid > ThemeManager._START_RESOURCES_ID) {
if (mLastThemeResourceId != resid) {
mActionBarContext = null;
super.setTheme(mLastThemeResourceId = resid);
}
} else {
if ((resid & ThemeManager.COLOR_SCHEME_MASK) == 0) {
resid &= ~ThemeManager.COLOR_SCHEME_MASK;
final int parentColorScheme = ThemeManager.getParentColorScheme(getIntent());
if (parentColorScheme != ThemeManager.INVALID) {
resid |= parentColorScheme;
} else {
resid |= ThemeManager.getDefaultTheme() & ThemeManager.COLOR_SCHEME_MASK;
}
}
setTheme(ThemeManager.getThemeResource(resid, modifyGlobal));
}
}
@SuppressLint("NewApi")
@Override
public void startActivities(Intent[] intents) {
startActivities(intents, null);
}
@SuppressLint("NewApi")
@Override
public void startActivities(Intent[] intents, Bundle options) {
for (Intent intent : intents) {
startActivity(intent, options);
}
}
@SuppressLint("NewApi")
@Override
public void startActivity(Intent intent) {
startActivity(intent, null);
}
@SuppressLint("NewApi")
@Override
public void startActivity(Intent intent, Bundle options) {
startActivityForResult(intent, -1, options);
}
@SuppressLint("NewApi")
@Override
public void startActivityForResult(Intent intent, int requestCode) {
startActivityForResult(intent, requestCode, null);
}
@Override
public void startActivityForResult(Intent intent, int requestCode,
Bundle options) {
if (HoloEverywhere.ALWAYS_USE_PARENT_THEME) {
ThemeManager.startActivity(this, intent, requestCode, options);
} else {
superStartActivity(intent, requestCode, options);
}
}
public android.content.SharedPreferences superGetSharedPreferences(
String name, int mode) {
return super.getSharedPreferences(name, mode);
}
@Override
public Object superGetSystemService(String name) {
return super.getSystemService(name);
}
@Override
@SuppressLint("NewApi")
public void superStartActivity(Intent intent, int requestCode,
Bundle options) {
if (VERSION.SDK_INT >= 16) {
super.startActivityForResult(intent, requestCode, options);
} else {
super.startActivityForResult(intent, requestCode);
}
}
@Override
public void onContextMenuClosed(ContextMenu menu) {
}
@Override
public void unregisterForContextMenu(View view) {
if (mContextMenuListeners != null) {
mContextMenuListeners.remove(view);
}
view.setLongClickable(false);
}
public static interface OnWindowFocusChangeListener {
public void onWindowFocusChanged(boolean hasFocus);
}
public static final class Holo implements Parcelable {
public static final Parcelable.Creator<Holo> CREATOR = new Creator<Holo>() {
@Override
public Holo createFromParcel(Parcel source) {
return new Holo(source);
}
@Override
public Holo[] newArray(int size) {
return new Holo[size];
}
};
public boolean ignoreApplicationInstanceCheck = false;
public boolean ignoreThemeCheck = false;
public boolean allowMockApplicationInstance = false;
private SparseIntArray windowFeatures;
private boolean mForbidRequestWindowFeature = false;
public Holo() {
}
private Holo(Parcel source) {
ignoreThemeCheck = source.readInt() == 1;
ignoreApplicationInstanceCheck = source.readInt() == 1;
allowMockApplicationInstance = source.readInt() == 1;
windowFeatures = source.readParcelable(SparseIntArray.class.getClassLoader());
}
public static Holo defaultConfig() {
return new Holo();
}
@Override
public int describeContents() {
return 0;
}
public void requestWindowFeature(int feature) {
if (windowFeatures == null) {
windowFeatures = new SparseIntArray();
}
if (mForbidRequestWindowFeature && windowFeatures.get(feature, -1) == -1) {
throw new RuntimeException("Request of window features forbid now. Something is broken.");
}
windowFeatures.put(feature, feature);
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(ignoreThemeCheck ? 1 : 0);
dest.writeInt(ignoreApplicationInstanceCheck ? 1 : 0);
dest.writeInt(allowMockApplicationInstance ? 1 : 0);
dest.writeParcelable(windowFeatures, flags);
}
private void requestWindowFeature(Activity holoActivity) {
mForbidRequestWindowFeature = true;
if (windowFeatures != null) {
for (int i = 0; i < windowFeatures.size(); i++) {
if (windowFeatures.valueAt(i) > 0) {
holoActivity.supportRequestWindowFeature(windowFeatures.keyAt(i));
}
}
}
mForbidRequestWindowFeature = false;
}
}
private static final class HoloThemeException extends RuntimeException {
private static final long serialVersionUID = -2346897999325868420L;
public HoloThemeException(_HoloActivity activity) {
super("You must apply Holo.Theme, Holo.Theme.Light or "
+ "Holo.Theme.Light.DarkActionBar theme on the activity ("
+ activity.getClass().getSimpleName()
+ ") for using HoloEverywhere");
}
}
private final class ActivityDecorView extends WindowDecorView {
public ActivityDecorView() {
super(_HoloActivity.this);
}
@Override
protected boolean fitSystemWindows(Rect insets) {
final SparseIntArray windowFeatures = createConfig(null).windowFeatures;
if (windowFeatures != null
&& windowFeatures.get(Window.FEATURE_ACTION_BAR_OVERLAY, 0) != 0) {
return false;
}
return super.fitSystemWindows(insets);
}
}
}