package org.robolectric.shadows;

import static android.os.Build.VERSION_CODES.JELLY_BEAN;
import static android.os.Build.VERSION_CODES.LOLLIPOP;
import static android.os.Build.VERSION_CODES.M;
import static org.robolectric.shadow.api.Shadow.directlyOn;

import android.R;
import android.app.Activity;
import android.app.ActivityManager;
import android.app.ActivityThread;
import android.app.Application;
import android.app.Dialog;
import android.app.Instrumentation;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.res.Configuration;
import android.database.Cursor;
import android.os.Build;
import android.os.Bundle;
import android.os.IBinder;
import android.text.Selection;
import android.text.SpannableStringBuilder;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewRootImpl;
import android.view.Window;
import com.android.internal.app.IVoiceInteractor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.HiddenApi;
import org.robolectric.annotation.Implementation;
import org.robolectric.annotation.Implements;
import org.robolectric.annotation.RealObject;
import org.robolectric.fakes.RoboMenuItem;
import org.robolectric.shadow.api.Shadow;
import org.robolectric.util.ReflectionHelpers;

@Implements(Activity.class)
public class ShadowActivity extends ShadowContextThemeWrapper {

  @RealObject
  protected Activity realActivity;

  private int resultCode;
  private Intent resultIntent;
  private Activity parent;
  private int requestedOrientation = -1;
  private View currentFocus;
  private Integer lastShownDialogId = null;
  private int pendingTransitionEnterAnimResId = -1;
  private int pendingTransitionExitAnimResId = -1;
  private Object lastNonConfigurationInstance;
  private Map<Integer, Dialog> dialogForId = new HashMap<>();
  private ArrayList<Cursor> managedCursors = new ArrayList<>();
  private int mDefaultKeyMode = Activity.DEFAULT_KEYS_DISABLE;
  private SpannableStringBuilder mDefaultKeySsb = null;
  private int streamType = -1;
  private boolean mIsTaskRoot = true;
  private Menu optionsMenu;
  private ComponentName callingActivity;
  private String callingPackage;
  private boolean isLockTask;
  private PermissionsRequest lastRequestedPermission;

  public void setApplication(Application application) {
    ReflectionHelpers.setField(realActivity, "mApplication", application);
  }

  public void callAttach(Intent intent) {
    int apiLevel = RuntimeEnvironment.getApiLevel();
    Application application = RuntimeEnvironment.application;
    Context baseContext = RuntimeEnvironment.application.getBaseContext();
    Class<?> nonConfigurationInstancesClass = getNonConfigurationClass();

    ActivityInfo activityInfo;
    try {
      activityInfo = application.getPackageManager().getActivityInfo(new ComponentName(application.getPackageName(), realActivity.getClass().getName()), PackageManager.GET_ACTIVITIES | PackageManager.GET_META_DATA);
    } catch (NameNotFoundException e) {
      throw new RuntimeException();
    }

    CharSequence activityTitle = activityInfo.loadLabel(baseContext.getPackageManager());

    Instrumentation instrumentation =
        ((ActivityThread) RuntimeEnvironment.getActivityThread()).getInstrumentation();
    if (apiLevel <= Build.VERSION_CODES.KITKAT) {
      ReflectionHelpers.callInstanceMethod(
          Activity.class,
          realActivity,
          "attach",
          ReflectionHelpers.ClassParameter.from(Context.class, baseContext),
          ReflectionHelpers.ClassParameter.from(
              ActivityThread.class, RuntimeEnvironment.getActivityThread()),
          ReflectionHelpers.ClassParameter.from(Instrumentation.class, instrumentation),
          ReflectionHelpers.ClassParameter.from(IBinder.class, null),
          ReflectionHelpers.ClassParameter.from(int.class, 0),
          ReflectionHelpers.ClassParameter.from(Application.class, application),
          ReflectionHelpers.ClassParameter.from(Intent.class, intent),
          ReflectionHelpers.ClassParameter.from(ActivityInfo.class, activityInfo),
          ReflectionHelpers.ClassParameter.from(CharSequence.class, activityTitle),
          ReflectionHelpers.ClassParameter.from(Activity.class, null),
          ReflectionHelpers.ClassParameter.from(String.class, "id"),
          ReflectionHelpers.ClassParameter.from(nonConfigurationInstancesClass, null),
          ReflectionHelpers.ClassParameter.from(
              Configuration.class, application.getResources().getConfiguration()));
    } else if (apiLevel <= Build.VERSION_CODES.LOLLIPOP) {
      ReflectionHelpers.callInstanceMethod(
          Activity.class,
          realActivity,
          "attach",
          ReflectionHelpers.ClassParameter.from(Context.class, baseContext),
          ReflectionHelpers.ClassParameter.from(
              ActivityThread.class, RuntimeEnvironment.getActivityThread()),
          ReflectionHelpers.ClassParameter.from(Instrumentation.class, instrumentation),
          ReflectionHelpers.ClassParameter.from(IBinder.class, null),
          ReflectionHelpers.ClassParameter.from(int.class, 0),
          ReflectionHelpers.ClassParameter.from(Application.class, application),
          ReflectionHelpers.ClassParameter.from(Intent.class, intent),
          ReflectionHelpers.ClassParameter.from(ActivityInfo.class, activityInfo),
          ReflectionHelpers.ClassParameter.from(CharSequence.class, activityTitle),
          ReflectionHelpers.ClassParameter.from(Activity.class, null),
          ReflectionHelpers.ClassParameter.from(String.class, "id"),
          ReflectionHelpers.ClassParameter.from(nonConfigurationInstancesClass, null),
          ReflectionHelpers.ClassParameter.from(
              Configuration.class, application.getResources().getConfiguration()),
          ReflectionHelpers.ClassParameter.from(IVoiceInteractor.class, null)); // ADDED
    } else if (apiLevel <= Build.VERSION_CODES.M) {
      ReflectionHelpers.callInstanceMethod(
          Activity.class,
          realActivity,
          "attach",
          ReflectionHelpers.ClassParameter.from(Context.class, baseContext),
          ReflectionHelpers.ClassParameter.from(
              ActivityThread.class, RuntimeEnvironment.getActivityThread()),
          ReflectionHelpers.ClassParameter.from(Instrumentation.class, instrumentation),
          ReflectionHelpers.ClassParameter.from(IBinder.class, null),
          ReflectionHelpers.ClassParameter.from(int.class, 0),
          ReflectionHelpers.ClassParameter.from(Application.class, application),
          ReflectionHelpers.ClassParameter.from(Intent.class, intent),
          ReflectionHelpers.ClassParameter.from(ActivityInfo.class, activityInfo),
          ReflectionHelpers.ClassParameter.from(CharSequence.class, activityTitle),
          ReflectionHelpers.ClassParameter.from(Activity.class, null),
          ReflectionHelpers.ClassParameter.from(String.class, "id"),
          ReflectionHelpers.ClassParameter.from(nonConfigurationInstancesClass, null),
          ReflectionHelpers.ClassParameter.from(
              Configuration.class, application.getResources().getConfiguration()),
          ReflectionHelpers.ClassParameter.from(String.class, "referrer"),
          ReflectionHelpers.ClassParameter.from(
              IVoiceInteractor.class, null)); // SAME AS LOLLIPOP ---------------------------
    } else if (apiLevel <= Build.VERSION_CODES.N_MR1) {
      ReflectionHelpers.callInstanceMethod(
          Activity.class,
          realActivity,
          "attach",
          ReflectionHelpers.ClassParameter.from(Context.class, baseContext),
          ReflectionHelpers.ClassParameter.from(
              ActivityThread.class, RuntimeEnvironment.getActivityThread()),
          ReflectionHelpers.ClassParameter.from(Instrumentation.class, instrumentation),
          ReflectionHelpers.ClassParameter.from(IBinder.class, null),
          ReflectionHelpers.ClassParameter.from(int.class, 0),
          ReflectionHelpers.ClassParameter.from(Application.class, application),
          ReflectionHelpers.ClassParameter.from(Intent.class, intent),
          ReflectionHelpers.ClassParameter.from(ActivityInfo.class, activityInfo),
          ReflectionHelpers.ClassParameter.from(CharSequence.class, activityTitle),
          ReflectionHelpers.ClassParameter.from(Activity.class, null),
          ReflectionHelpers.ClassParameter.from(String.class, "id"),
          ReflectionHelpers.ClassParameter.from(nonConfigurationInstancesClass, null),
          ReflectionHelpers.ClassParameter.from(
              Configuration.class, application.getResources().getConfiguration()),
          ReflectionHelpers.ClassParameter.from(String.class, "referrer"),
          ReflectionHelpers.ClassParameter.from(IVoiceInteractor.class, null),
          ReflectionHelpers.ClassParameter.from(Window.class, null) // ADDED
          );
    } else if (apiLevel <= Build.VERSION_CODES.P) {
      ReflectionHelpers.callInstanceMethod(
          Activity.class,
          realActivity,
          "attach",
          ReflectionHelpers.ClassParameter.from(Context.class, baseContext),
          ReflectionHelpers.ClassParameter.from(
              ActivityThread.class, RuntimeEnvironment.getActivityThread()),
          ReflectionHelpers.ClassParameter.from(Instrumentation.class, instrumentation),
          ReflectionHelpers.ClassParameter.from(IBinder.class, null),
          ReflectionHelpers.ClassParameter.from(int.class, 0),
          ReflectionHelpers.ClassParameter.from(Application.class, application),
          ReflectionHelpers.ClassParameter.from(Intent.class, intent),
          ReflectionHelpers.ClassParameter.from(ActivityInfo.class, activityInfo),
          ReflectionHelpers.ClassParameter.from(CharSequence.class, activityTitle),
          ReflectionHelpers.ClassParameter.from(Activity.class, null),
          ReflectionHelpers.ClassParameter.from(String.class, "id"),
          ReflectionHelpers.ClassParameter.from(nonConfigurationInstancesClass, null),
          ReflectionHelpers.ClassParameter.from(
              Configuration.class, application.getResources().getConfiguration()),
          ReflectionHelpers.ClassParameter.from(String.class, "referrer"),
          ReflectionHelpers.ClassParameter.from(IVoiceInteractor.class, null),
          ReflectionHelpers.ClassParameter.from(Window.class, null),
          ReflectionHelpers.ClassParameter.from(
              ViewRootImpl.ActivityConfigCallback.class, null) // ADDED
          );
    } else if (apiLevel >= Build.VERSION_CODES.Q) {
      ReflectionHelpers.callInstanceMethod(
          Activity.class,
          realActivity,
          "attach",
          ReflectionHelpers.ClassParameter.from(Context.class, baseContext),
          ReflectionHelpers.ClassParameter.from(
                  ActivityThread.class, RuntimeEnvironment.getActivityThread()),
          ReflectionHelpers.ClassParameter.from(Instrumentation.class, instrumentation),
          ReflectionHelpers.ClassParameter.from(IBinder.class, null),
          ReflectionHelpers.ClassParameter.from(int.class, 0),
          ReflectionHelpers.ClassParameter.from(Application.class, application),
          ReflectionHelpers.ClassParameter.from(Intent.class, intent),
          ReflectionHelpers.ClassParameter.from(ActivityInfo.class, activityInfo),
          ReflectionHelpers.ClassParameter.from(CharSequence.class, activityTitle),
          ReflectionHelpers.ClassParameter.from(Activity.class, null),
          ReflectionHelpers.ClassParameter.from(String.class, "id"),
          ReflectionHelpers.ClassParameter.from(nonConfigurationInstancesClass, null),
          ReflectionHelpers.ClassParameter.from(
                  Configuration.class, application.getResources().getConfiguration()),
          ReflectionHelpers.ClassParameter.from(String.class, "referrer"),
          ReflectionHelpers.ClassParameter.from(IVoiceInteractor.class, null),
          ReflectionHelpers.ClassParameter.from(Window.class, null),
          ReflectionHelpers.ClassParameter.from(
                  ViewRootImpl.ActivityConfigCallback.class, null),
          ReflectionHelpers.ClassParameter.from(IBinder.class, null) // ADDED
      );
    } else {
      throw new RuntimeException("Could not find AndroidRuntimeAdapter for API level: " + apiLevel);
    }

    int theme = activityInfo.getThemeResource();
    if (theme != 0) {
      realActivity.setTheme(theme);
    }
  }

  private Class<?> getNonConfigurationClass() {
    try {
      return getClass().getClassLoader().loadClass("android.app.Activity$NonConfigurationInstances");
    } catch (ClassNotFoundException e) {
      throw new RuntimeException(e);
    }
  }

  public void setCallingActivity(ComponentName activityName) {
    callingActivity = activityName;
  }

  @Implementation
  protected ComponentName getCallingActivity() {
    return callingActivity;
  }

  public void setCallingPackage(String packageName) {
    callingPackage = packageName;
  }

  @Implementation
  protected String getCallingPackage() {
    return callingPackage;
  }

  @Implementation
  protected void setDefaultKeyMode(int keyMode) {
    mDefaultKeyMode = keyMode;

    // Some modes use a SpannableStringBuilder to track & dispatch input events
    // This list must remain in sync with the switch in onKeyDown()
    switch (mDefaultKeyMode) {
      case Activity.DEFAULT_KEYS_DISABLE:
      case Activity.DEFAULT_KEYS_SHORTCUT:
        mDefaultKeySsb = null;      // not used in these modes
        break;
      case Activity.DEFAULT_KEYS_DIALER:
      case Activity.DEFAULT_KEYS_SEARCH_LOCAL:
      case Activity.DEFAULT_KEYS_SEARCH_GLOBAL:
        mDefaultKeySsb = new SpannableStringBuilder();
        Selection.setSelection(mDefaultKeySsb, 0);
        break;
      default:
        throw new IllegalArgumentException();
    }
  }

  public int getDefaultKeymode() {
    return mDefaultKeyMode;
  }

  @Implementation
  protected final void setResult(int resultCode) {
    this.resultCode = resultCode;
  }

  @Implementation
  protected final void setResult(int resultCode, Intent data) {
    this.resultCode = resultCode;
    this.resultIntent = data;
  }

  @Implementation
  protected LayoutInflater getLayoutInflater() {
    return LayoutInflater.from(realActivity);
  }

  @Implementation
  protected MenuInflater getMenuInflater() {
    return new MenuInflater(realActivity);
  }

  /**
   * Checks to ensure that the{@code contentView} has been set
   *
   * @param id ID of the view to find
   * @return the view
   * @throws RuntimeException if the {@code contentView} has not been called first
   */
  @Implementation
  protected View findViewById(int id) {
    return getWindow().findViewById(id);
  }

  @Implementation
  protected final Activity getParent() {
    return parent;
  }

  /**
   * Allow setting of Parent fragmentActivity (for unit testing purposes only)
   *
   * @param parent Parent fragmentActivity to set on this fragmentActivity
   */
  @HiddenApi @Implementation
  public void setParent(Activity parent) {
    this.parent = parent;
  }

  @Implementation
  protected void onBackPressed() {
    finish();
  }

  @Implementation
  protected void finish() {
    // Sets the mFinished field in the real activity so NoDisplay activities can be tested.
    ReflectionHelpers.setField(Activity.class, realActivity, "mFinished", true);
  }

  @Implementation(minSdk = LOLLIPOP)
  protected void finishAndRemoveTask() {
    // Sets the mFinished field in the real activity so NoDisplay activities can be tested.
    ReflectionHelpers.setField(Activity.class, realActivity, "mFinished", true);
  }

  @Implementation(minSdk = JELLY_BEAN)
  protected void finishAffinity() {
    // Sets the mFinished field in the real activity so NoDisplay activities can be tested.
    ReflectionHelpers.setField(Activity.class, realActivity, "mFinished", true);
  }

  public void resetIsFinishing() {
    ReflectionHelpers.setField(Activity.class, realActivity, "mFinished", false);
  }

  /**
   * Returns whether {@link #finish()} was called.
   *
   * @deprecated Use {@link Activity#isFinishing()} instead.
   */
  @Deprecated
  public boolean isFinishing() {
    return directlyOn(realActivity, Activity.class).isFinishing();
  }

  /**
   * Constructs a new Window (a {@link com.android.internal.policy.impl.PhoneWindow}) if no window
   * has previously been set.
   *
   * @return the window associated with this Activity
   */
  @Implementation
  protected Window getWindow() {
    Window window = directlyOn(realActivity, Activity.class).getWindow();

    if (window == null) {
      try {
        window = ShadowWindow.create(realActivity);
        setWindow(window);
      } catch (Exception e) {
        throw new RuntimeException("Window creation failed!", e);
      }
    }

    return window;
  }

  public void setWindow(Window window) {
    ReflectionHelpers.setField(realActivity, "mWindow", window);
  }

  @Implementation
  protected void runOnUiThread(Runnable action) {
    ShadowApplication.getInstance().getForegroundThreadScheduler().post(action);
  }

  @Implementation
  protected void setRequestedOrientation(int requestedOrientation) {
    if (getParent() != null) {
      getParent().setRequestedOrientation(requestedOrientation);
    } else {
      this.requestedOrientation = requestedOrientation;
    }
  }

  @Implementation
  protected int getRequestedOrientation() {
    if (getParent() != null) {
      return getParent().getRequestedOrientation();
    } else {
      return this.requestedOrientation;
    }
  }

  @Implementation
  protected int getTaskId() {
    return 0;
  }

  /**
   * @return the {@code contentView} set by one of the {@code setContentView()} methods
   */
  public View getContentView() {
    return ((ViewGroup) getWindow().findViewById(R.id.content)).getChildAt(0);
  }

  /**
   * @return the {@code resultCode} set by one of the {@code setResult()} methods
   */
  public int getResultCode() {
    return resultCode;
  }

  /**
   * @return the {@code Intent} set by {@link #setResult(int, android.content.Intent)}
   */
  public Intent getResultIntent() {
    return resultIntent;
  }

  /**
   * Consumes and returns the next {@code Intent} on the
   * started activities for results stack.
   *
   * @return the next started {@code Intent} for an activity, wrapped in
   *         an {@link ShadowActivity.IntentForResult} object
   */
  public IntentForResult getNextStartedActivityForResult() {
    ActivityThread activityThread = (ActivityThread) RuntimeEnvironment.getActivityThread();
    ShadowInstrumentation shadowInstrumentation = Shadow.extract(activityThread.getInstrumentation());
    return shadowInstrumentation.getNextStartedActivityForResult();
  }

  /**
   * Returns the most recent {@code Intent} started by
   * {@link Activity#startActivityForResult(Intent, int)} without consuming it.
   *
   * @return the most recently started {@code Intent}, wrapped in
   *         an {@link ShadowActivity.IntentForResult} object
   */
  public IntentForResult peekNextStartedActivityForResult() {
    ActivityThread activityThread = (ActivityThread) RuntimeEnvironment.getActivityThread();
    ShadowInstrumentation shadowInstrumentation = Shadow.extract(activityThread.getInstrumentation());
    return shadowInstrumentation.peekNextStartedActivityForResult();
  }

  @Implementation
  protected Object getLastNonConfigurationInstance() {
    return lastNonConfigurationInstance;
  }

  public void setLastNonConfigurationInstance(Object lastNonConfigurationInstance) {
    this.lastNonConfigurationInstance = lastNonConfigurationInstance;
  }

  /**
   * @param view View to focus.
   */
  public void setCurrentFocus(View view) {
    currentFocus = view;
  }

  @Implementation
  protected View getCurrentFocus() {
    return currentFocus;
  }

  public int getPendingTransitionEnterAnimationResourceId() {
    return pendingTransitionEnterAnimResId;
  }

  public int getPendingTransitionExitAnimationResourceId() {
    return pendingTransitionExitAnimResId;
  }

  @Implementation
  protected boolean onCreateOptionsMenu(Menu menu) {
    optionsMenu = menu;
    return directlyOn(realActivity, Activity.class).onCreateOptionsMenu(menu);
  }

  /**
   * Return the options menu.
   *
   * @return  Options menu.
   */
  public Menu getOptionsMenu() {
    return optionsMenu;
  }

  /**
   * Perform a click on a menu item.
   *
   * @param menuItemResId Menu item resource ID.
   * @return True if the click was handled, false otherwise.
   */
  public boolean clickMenuItem(int menuItemResId) {
    final RoboMenuItem item = new RoboMenuItem(menuItemResId);
    return realActivity.onMenuItemSelected(Window.FEATURE_OPTIONS_PANEL, item);
  }

  /** For internal use only. Not for public use. */
  public void callOnActivityResult(int requestCode, int resultCode, Intent resultData) {
    final ActivityInvoker invoker = new ActivityInvoker();
    invoker
        .call("onActivityResult", Integer.TYPE, Integer.TYPE, Intent.class)
        .with(requestCode, resultCode, resultData);
  }

  /**
   * Container object to hold an Intent, together with the requestCode used
   * in a call to {@code Activity.startActivityForResult(Intent, int)}
   */
  public static class IntentForResult {
    public Intent intent;
    public int requestCode;
    public Bundle options;

    public IntentForResult(Intent intent, int requestCode) {
      this.intent = intent;
      this.requestCode = requestCode;
      this.options = null;
    }

    public IntentForResult(Intent intent, int requestCode, Bundle options) {
      this.intent = intent;
      this.requestCode = requestCode;
      this.options = options;
    }
  }

  public void receiveResult(Intent requestIntent, int resultCode, Intent resultIntent) {
    ActivityThread activityThread = (ActivityThread) RuntimeEnvironment.getActivityThread();
    ShadowInstrumentation shadowInstrumentation = Shadow.extract(activityThread.getInstrumentation());
    int requestCode = shadowInstrumentation.getRequestCodeForIntent(requestIntent);

    callOnActivityResult(requestCode, resultCode, resultIntent);
  }

  @Implementation
  protected final void showDialog(int id) {
    showDialog(id, null);
  }

  @Implementation
  protected final void dismissDialog(int id) {
    final Dialog dialog = dialogForId.get(id);
    if (dialog == null) {
      throw new IllegalArgumentException();
    }

    dialog.dismiss();
  }

  @Implementation
  protected final void removeDialog(int id) {
    dialogForId.remove(id);
  }

  @Implementation
  protected final boolean showDialog(int id, Bundle bundle) {
    this.lastShownDialogId = id;
    Dialog dialog = dialogForId.get(id);

    if (dialog == null) {
      final ActivityInvoker invoker = new ActivityInvoker();
      dialog = (Dialog) invoker.call("onCreateDialog", Integer.TYPE).with(id);
      if (dialog == null) {
        return false;
      }
      if (bundle == null) {
        invoker.call("onPrepareDialog", Integer.TYPE, Dialog.class).with(id, dialog);
      } else {
        invoker.call("onPrepareDialog", Integer.TYPE, Dialog.class, Bundle.class).with(id, dialog, bundle);
      }

      dialogForId.put(id, dialog);
    }

    dialog.show();
    return true;
  }

  public void setIsTaskRoot(boolean isRoot) {
    mIsTaskRoot = isRoot;
  }

  @Implementation
  protected final boolean isTaskRoot() {
    return mIsTaskRoot;
  }

  /**
   * @return the dialog resource id passed into
   *         {@code Activity.showDialog(int, Bundle)} or {@code Activity.showDialog(int)}
   */
  public Integer getLastShownDialogId() {
    return lastShownDialogId;
  }

  public boolean hasCancelledPendingTransitions() {
    return pendingTransitionEnterAnimResId == 0 && pendingTransitionExitAnimResId == 0;
  }

  @Implementation
  protected void overridePendingTransition(int enterAnim, int exitAnim) {
    pendingTransitionEnterAnimResId = enterAnim;
    pendingTransitionExitAnimResId = exitAnim;
  }

  public Dialog getDialogById(int dialogId) {
    return dialogForId.get(dialogId);
  }

  @Implementation
  protected void recreate() {
    Bundle outState = new Bundle();
    final ActivityInvoker invoker = new ActivityInvoker();

    invoker.call("onSaveInstanceState", Bundle.class).with(outState);
    invoker.call("onPause").withNothing();
    invoker.call("onStop").withNothing();

    Object nonConfigInstance = invoker.call("onRetainNonConfigurationInstance").withNothing();
    setLastNonConfigurationInstance(nonConfigInstance);

    invoker.call("onDestroy").withNothing();
    invoker.call("onCreate", Bundle.class).with(outState);
    invoker.call("onStart").withNothing();
    invoker.call("onRestoreInstanceState", Bundle.class).with(outState);
    invoker.call("onResume").withNothing();
  }

  @Implementation
  protected void startManagingCursor(Cursor c) {
    managedCursors.add(c);
  }

  @Implementation
  protected void stopManagingCursor(Cursor c) {
    managedCursors.remove(c);
  }

  public List<Cursor> getManagedCursors() {
    return managedCursors;
  }

  @Implementation
  protected final void setVolumeControlStream(int streamType) {
    this.streamType = streamType;
  }

  @Implementation
  protected final int getVolumeControlStream() {
    return streamType;
  }

  @Implementation(minSdk = M)
  protected final void requestPermissions(String[] permissions, int requestCode) {
    lastRequestedPermission = new PermissionsRequest(permissions, requestCode);
  }

  /**
   * Starts a lock task.
   *
   * <p>The status of the lock task can be verified using {@link #isLockTask} method. Otherwise this
   * implementation has no effect.
   */
  @Implementation(minSdk = LOLLIPOP)
  protected void startLockTask() {
    Shadow.<ShadowActivityManager>extract(getActivityManager())
        .setLockTaskModeState(ActivityManager.LOCK_TASK_MODE_LOCKED);
  }

  /**
   * Stops a lock task.
   *
   * <p>The status of the lock task can be verified using {@link #isLockTask} method. Otherwise this
   * implementation has no effect.
   */
  @Implementation(minSdk = LOLLIPOP)
  protected void stopLockTask() {
    Shadow.<ShadowActivityManager>extract(getActivityManager())
        .setLockTaskModeState(ActivityManager.LOCK_TASK_MODE_NONE);
  }

  /**
   * Returns if the activity is in the lock task mode.
   *
   * @deprecated Use {@link ActivityManager#getLockTaskModeState} instead.
   */
  @Deprecated
  public boolean isLockTask() {
    return getActivityManager().isInLockTaskMode();
  }

  private ActivityManager getActivityManager() {
    return (ActivityManager) realActivity.getSystemService(Context.ACTIVITY_SERVICE);
  }

  /**
   * Gets the last permission request submitted to this activity.
   *
   * @return The permission request details.
   */
  public PermissionsRequest getLastRequestedPermission() {
    return lastRequestedPermission;
  }

  private final class ActivityInvoker {
    private Method method;

    public ActivityInvoker call(final String methodName, final Class... argumentClasses) {
      try {
        method = Activity.class.getDeclaredMethod(methodName, argumentClasses);
        method.setAccessible(true);
        return this;
      } catch (NoSuchMethodException e) {
        throw new RuntimeException(e);
      }
    }

    public Object withNothing() {
      return with();
    }

    public Object with(final Object... parameters) {
      try {
        return method.invoke(realActivity, parameters);
      } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
        throw new RuntimeException(e);
      }
    }
  }

  /** Class to hold a permissions request, including its request code. */
  public static class PermissionsRequest {
    public final int requestCode;
    public final String[] requestedPermissions;

    public PermissionsRequest(String[] requestedPermissions, int requestCode) {
      this.requestedPermissions = requestedPermissions;
      this.requestCode = requestCode;
    }
  }
}
