1package com.xtremelabs.robolectric.shadows;
2
3import android.os.Bundle;
4import android.support.v4.app.Fragment;
5import android.support.v4.app.FragmentActivity;
6import android.support.v4.app.FragmentManager;
7import android.view.View;
8
9import com.xtremelabs.robolectric.internal.Implementation;
10import com.xtremelabs.robolectric.internal.Implements;
11import com.xtremelabs.robolectric.internal.RealObject;
12import com.xtremelabs.robolectric.tester.android.util.TestFragmentManager;
13
14import java.util.ArrayList;
15import java.util.List;
16import java.util.Map;
17
18import static com.xtremelabs.robolectric.Robolectric.shadowOf;
19
20@Implements(FragmentActivity.class)
21public class ShadowFragmentActivity extends ShadowActivity {
22    @RealObject
23    FragmentActivity realObject;
24
25    private TestFragmentManager fragmentManager;
26    public static final String FRAGMENTS_TAG = "android:fragments";
27
28    public void __constructor__() {
29        fragmentManager = new TestFragmentManager(realObject);
30    }
31
32    @Implementation
33    public void onCreate(Bundle bundle) {
34        super.onCreate(bundle);
35
36        if (bundle != null && bundle.containsKey(FRAGMENTS_TAG)) {
37            Object[] fragments = (Object[]) bundle.getSerializable(FRAGMENTS_TAG);
38
39            for (Object o : fragments) {
40                SerializedFragmentState fragmentState = (SerializedFragmentState) o;
41
42                try {
43                    Fragment fragment = fragmentState.fragmentClass.newInstance();
44                    shadowOf(fragment).setSavedInstanceState(bundle);
45
46                    fragmentManager.addFragment(fragmentState.containerId, fragmentState.tag, fragment, true);
47                } catch (InstantiationException e) {
48                    throw new RuntimeException(e);
49                } catch (IllegalAccessException e) {
50                    throw new RuntimeException(e);
51                }
52            }
53        }
54    }
55
56    @Implementation
57    public void onStart() {
58        for (Fragment fragment : fragmentManager.getFragments()) {
59            fragmentManager.startFragment(fragment);
60        }
61    }
62
63    @Implementation
64    public void onPause() {
65        for(Fragment fragment : fragmentManager.getFragments()) {
66            fragment.onPause();
67        }
68    }
69
70    @Implementation
71    public FragmentManager getSupportFragmentManager() {
72        return fragmentManager;
73    }
74
75    @Implementation
76    public void onSaveInstanceState(Bundle outState) {
77        // We cannot figure out how to pass the RobolectricWiring test without doing this incredibly
78        // terrible looking hack.  I am very sorry.
79        List<SerializedFragmentState> fragmentStates = new ArrayList<SerializedFragmentState>();
80
81        for (Map.Entry<Integer, Fragment> entry : fragmentManager.getFragmentsById().entrySet()) {
82            Fragment fragment = entry.getValue();
83            fragment.onSaveInstanceState(outState);
84            fragmentStates.add(new SerializedFragmentState(entry.getKey(), fragment));
85        }
86
87        outState.putSerializable(FRAGMENTS_TAG, fragmentStates.toArray());
88    }
89
90    @Implementation
91    @Override
92    public View getCurrentFocus() {
93        View focusedView = super.getCurrentFocus();
94        if (focusedView != null) {
95            return focusedView;
96        }
97
98        for (Fragment fragment : fragmentManager.getFragments()) {
99            View view = shadowOf(fragment).view;
100            if (view != null) {
101                focusedView = view.findFocus();
102                if (focusedView != null) {
103                    return focusedView;
104                }
105            }
106        }
107        return null;
108    }
109
110    @Override
111    public void clearFocus() {
112        super.clearFocus();
113
114        for (Fragment fragment : fragmentManager.getFragments()) {
115            View view = shadowOf(fragment).view;
116            if (view != null) {
117                view.clearFocus();
118            }
119        }
120    }
121}
122