1 /*
2  * Copyright (C) 2015 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package android.app;
18 
19 import android.annotation.Nullable;
20 import android.compat.annotation.UnsupportedAppUsage;
21 import android.content.Context;
22 import android.content.res.Configuration;
23 import android.os.Bundle;
24 import android.os.Parcelable;
25 import android.util.ArrayMap;
26 import android.util.AttributeSet;
27 import android.view.Menu;
28 import android.view.MenuInflater;
29 import android.view.MenuItem;
30 import android.view.View;
31 
32 import java.io.FileDescriptor;
33 import java.io.PrintWriter;
34 import java.util.List;
35 
36 /**
37  * Provides integration points with a {@link FragmentManager} for a fragment host.
38  * <p>
39  * It is the responsibility of the host to take care of the Fragment's lifecycle.
40  * The methods provided by {@link FragmentController} are for that purpose.
41  *
42  * @deprecated Use the <a href="{@docRoot}tools/extras/support-library.html">Support Library</a>
43  *      {@link android.support.v4.app.FragmentController}
44  */
45 @Deprecated
46 public class FragmentController {
47     @UnsupportedAppUsage
48     private final FragmentHostCallback<?> mHost;
49 
50     /**
51      * Returns a {@link FragmentController}.
52      */
createController(FragmentHostCallback<?> callbacks)53     public static final FragmentController createController(FragmentHostCallback<?> callbacks) {
54         return new FragmentController(callbacks);
55     }
56 
FragmentController(FragmentHostCallback<?> callbacks)57     private FragmentController(FragmentHostCallback<?> callbacks) {
58         mHost = callbacks;
59     }
60 
61     /**
62      * Returns a {@link FragmentManager} for this controller.
63      */
getFragmentManager()64     public FragmentManager getFragmentManager() {
65         return mHost.getFragmentManagerImpl();
66     }
67 
68     /**
69      * Returns a {@link LoaderManager}.
70      */
getLoaderManager()71     public LoaderManager getLoaderManager() {
72         return mHost.getLoaderManagerImpl();
73     }
74 
75     /**
76      * Returns a fragment with the given identifier.
77      */
78     @Nullable
findFragmentByWho(String who)79     public Fragment findFragmentByWho(String who) {
80         return mHost.mFragmentManager.findFragmentByWho(who);
81     }
82 
83     /**
84      * Attaches the host to the FragmentManager for this controller. The host must be
85      * attached before the FragmentManager can be used to manage Fragments.
86      * */
attachHost(Fragment parent)87     public void attachHost(Fragment parent) {
88         mHost.mFragmentManager.attachController(
89                 mHost, mHost /*container*/, parent);
90     }
91 
92     /**
93      * Instantiates a Fragment's view.
94      *
95      * @param parent The parent that the created view will be placed
96      * in; <em>note that this may be null</em>.
97      * @param name Tag name to be inflated.
98      * @param context The context the view is being created in.
99      * @param attrs Inflation attributes as specified in XML file.
100      *
101      * @return view the newly created view
102      */
onCreateView(View parent, String name, Context context, AttributeSet attrs)103     public View onCreateView(View parent, String name, Context context, AttributeSet attrs) {
104         return mHost.mFragmentManager.onCreateView(parent, name, context, attrs);
105     }
106 
107     /**
108      * Marks the fragment state as unsaved. This allows for "state loss" detection.
109      */
noteStateNotSaved()110     public void noteStateNotSaved() {
111         mHost.mFragmentManager.noteStateNotSaved();
112     }
113 
114     /**
115      * Saves the state for all Fragments.
116      */
saveAllState()117     public Parcelable saveAllState() {
118         return mHost.mFragmentManager.saveAllState();
119     }
120 
121     /**
122      * Restores the saved state for all Fragments. The given Fragment list are Fragment
123      * instances retained across configuration changes.
124      *
125      * @see #retainNonConfig()
126      *
127      * @deprecated use {@link #restoreAllState(Parcelable, FragmentManagerNonConfig)}
128      */
129     @Deprecated
restoreAllState(Parcelable state, List<Fragment> nonConfigList)130     public void restoreAllState(Parcelable state, List<Fragment> nonConfigList) {
131         mHost.mFragmentManager.restoreAllState(state,
132                 new FragmentManagerNonConfig(nonConfigList, null));
133     }
134 
135     /**
136      * Restores the saved state for all Fragments. The given FragmentManagerNonConfig are Fragment
137      * instances retained across configuration changes, including nested fragments
138      *
139      * @see #retainNestedNonConfig()
140      */
restoreAllState(Parcelable state, FragmentManagerNonConfig nonConfig)141     public void restoreAllState(Parcelable state, FragmentManagerNonConfig nonConfig) {
142         mHost.mFragmentManager.restoreAllState(state, nonConfig);
143     }
144 
145     /**
146      * Returns a list of Fragments that have opted to retain their instance across
147      * configuration changes.
148      *
149      * @deprecated use {@link #retainNestedNonConfig()} to also track retained
150      *             nested child fragments
151      */
152     @Deprecated
retainNonConfig()153     public List<Fragment> retainNonConfig() {
154         return mHost.mFragmentManager.retainNonConfig().getFragments();
155     }
156 
157     /**
158      * Returns a nested tree of Fragments that have opted to retain their instance across
159      * configuration changes.
160      */
retainNestedNonConfig()161     public FragmentManagerNonConfig retainNestedNonConfig() {
162         return mHost.mFragmentManager.retainNonConfig();
163     }
164 
165     /**
166      * Moves all Fragments managed by the controller's FragmentManager
167      * into the create state.
168      * <p>Call when Fragments should be created.
169      *
170      * @see Fragment#onCreate(Bundle)
171      */
dispatchCreate()172     public void dispatchCreate() {
173         mHost.mFragmentManager.dispatchCreate();
174     }
175 
176     /**
177      * Moves all Fragments managed by the controller's FragmentManager
178      * into the activity created state.
179      * <p>Call when Fragments should be informed their host has been created.
180      *
181      * @see Fragment#onActivityCreated(Bundle)
182      */
dispatchActivityCreated()183     public void dispatchActivityCreated() {
184         mHost.mFragmentManager.dispatchActivityCreated();
185     }
186 
187     /**
188      * Moves all Fragments managed by the controller's FragmentManager
189      * into the start state.
190      * <p>Call when Fragments should be started.
191      *
192      * @see Fragment#onStart()
193      */
dispatchStart()194     public void dispatchStart() {
195         mHost.mFragmentManager.dispatchStart();
196     }
197 
198     /**
199      * Moves all Fragments managed by the controller's FragmentManager
200      * into the resume state.
201      * <p>Call when Fragments should be resumed.
202      *
203      * @see Fragment#onResume()
204      */
dispatchResume()205     public void dispatchResume() {
206         mHost.mFragmentManager.dispatchResume();
207     }
208 
209     /**
210      * Moves all Fragments managed by the controller's FragmentManager
211      * into the pause state.
212      * <p>Call when Fragments should be paused.
213      *
214      * @see Fragment#onPause()
215      */
dispatchPause()216     public void dispatchPause() {
217         mHost.mFragmentManager.dispatchPause();
218     }
219 
220     /**
221      * Moves all Fragments managed by the controller's FragmentManager
222      * into the stop state.
223      * <p>Call when Fragments should be stopped.
224      *
225      * @see Fragment#onStop()
226      */
dispatchStop()227     public void dispatchStop() {
228         mHost.mFragmentManager.dispatchStop();
229     }
230 
231     /**
232      * Moves all Fragments managed by the controller's FragmentManager
233      * into the destroy view state.
234      * <p>Call when the Fragment's views should be destroyed.
235      *
236      * @see Fragment#onDestroyView()
237      */
dispatchDestroyView()238     public void dispatchDestroyView() {
239         mHost.mFragmentManager.dispatchDestroyView();
240     }
241 
242     /**
243      * Moves all Fragments managed by the controller's FragmentManager
244      * into the destroy state.
245      * <p>Call when Fragments should be destroyed.
246      *
247      * @see Fragment#onDestroy()
248      */
dispatchDestroy()249     public void dispatchDestroy() {
250         mHost.mFragmentManager.dispatchDestroy();
251     }
252 
253     /**
254      * Lets all Fragments managed by the controller's FragmentManager know the multi-window mode of
255      * the activity changed.
256      * <p>Call when the multi-window mode of the activity changed.
257      *
258      * @see Fragment#onMultiWindowModeChanged
259      * @deprecated use {@link #dispatchMultiWindowModeChanged(boolean, Configuration)}
260      */
261     @Deprecated
dispatchMultiWindowModeChanged(boolean isInMultiWindowMode)262     public void dispatchMultiWindowModeChanged(boolean isInMultiWindowMode) {
263         mHost.mFragmentManager.dispatchMultiWindowModeChanged(isInMultiWindowMode);
264     }
265 
266     /**
267      * Lets all Fragments managed by the controller's FragmentManager know the multi-window mode of
268      * the activity changed.
269      * <p>Call when the multi-window mode of the activity changed.
270      *
271      * @see Fragment#onMultiWindowModeChanged
272      */
dispatchMultiWindowModeChanged(boolean isInMultiWindowMode, Configuration newConfig)273     public void dispatchMultiWindowModeChanged(boolean isInMultiWindowMode,
274             Configuration newConfig) {
275         mHost.mFragmentManager.dispatchMultiWindowModeChanged(isInMultiWindowMode, newConfig);
276     }
277 
278     /**
279      * Lets all Fragments managed by the controller's FragmentManager know the picture-in-picture
280      * mode of the activity changed.
281      * <p>Call when the picture-in-picture mode of the activity changed.
282      *
283      * @see Fragment#onPictureInPictureModeChanged
284      * @deprecated use {@link #dispatchPictureInPictureModeChanged(boolean, Configuration)}
285      */
286     @Deprecated
dispatchPictureInPictureModeChanged(boolean isInPictureInPictureMode)287     public void dispatchPictureInPictureModeChanged(boolean isInPictureInPictureMode) {
288         mHost.mFragmentManager.dispatchPictureInPictureModeChanged(isInPictureInPictureMode);
289     }
290 
291     /**
292      * Lets all Fragments managed by the controller's FragmentManager know the picture-in-picture
293      * mode of the activity changed.
294      * <p>Call when the picture-in-picture mode of the activity changed.
295      *
296      * @see Fragment#onPictureInPictureModeChanged
297      */
dispatchPictureInPictureModeChanged(boolean isInPictureInPictureMode, Configuration newConfig)298     public void dispatchPictureInPictureModeChanged(boolean isInPictureInPictureMode,
299             Configuration newConfig) {
300         mHost.mFragmentManager.dispatchPictureInPictureModeChanged(isInPictureInPictureMode,
301                 newConfig);
302     }
303 
304     /**
305      * Lets all Fragments managed by the controller's FragmentManager
306      * know a configuration change occurred.
307      * <p>Call when there is a configuration change.
308      *
309      * @see Fragment#onConfigurationChanged(Configuration)
310      */
dispatchConfigurationChanged(Configuration newConfig)311     public void dispatchConfigurationChanged(Configuration newConfig) {
312         mHost.mFragmentManager.dispatchConfigurationChanged(newConfig);
313     }
314 
315     /**
316      * Lets all Fragments managed by the controller's FragmentManager
317      * know the device is in a low memory condition.
318      * <p>Call when the device is low on memory and Fragment's should trim
319      * their memory usage.
320      *
321      * @see Fragment#onLowMemory()
322      */
dispatchLowMemory()323     public void dispatchLowMemory() {
324         mHost.mFragmentManager.dispatchLowMemory();
325     }
326 
327     /**
328      * Lets all Fragments managed by the controller's FragmentManager
329      * know they should trim their memory usage.
330      * <p>Call when the Fragment can release allocated memory [such as if
331      * the Fragment is in the background].
332      *
333      * @see Fragment#onTrimMemory(int)
334      */
dispatchTrimMemory(int level)335     public void dispatchTrimMemory(int level) {
336         mHost.mFragmentManager.dispatchTrimMemory(level);
337     }
338 
339     /**
340      * Lets all Fragments managed by the controller's FragmentManager
341      * know they should create an options menu.
342      * <p>Call when the Fragment should create an options menu.
343      *
344      * @return {@code true} if the options menu contains items to display
345      * @see Fragment#onCreateOptionsMenu(Menu, MenuInflater)
346      */
dispatchCreateOptionsMenu(Menu menu, MenuInflater inflater)347     public boolean dispatchCreateOptionsMenu(Menu menu, MenuInflater inflater) {
348         return mHost.mFragmentManager.dispatchCreateOptionsMenu(menu, inflater);
349     }
350 
351     /**
352      * Lets all Fragments managed by the controller's FragmentManager
353      * know they should prepare their options menu for display.
354      * <p>Call immediately before displaying the Fragment's options menu.
355      *
356      * @return {@code true} if the options menu contains items to display
357      * @see Fragment#onPrepareOptionsMenu(Menu)
358      */
dispatchPrepareOptionsMenu(Menu menu)359     public boolean dispatchPrepareOptionsMenu(Menu menu) {
360         return mHost.mFragmentManager.dispatchPrepareOptionsMenu(menu);
361     }
362 
363     /**
364      * Sends an option item selection event to the Fragments managed by the
365      * controller's FragmentManager. Once the event has been consumed,
366      * no additional handling will be performed.
367      * <p>Call immediately after an options menu item has been selected
368      *
369      * @return {@code true} if the options menu selection event was consumed
370      * @see Fragment#onOptionsItemSelected(MenuItem)
371      */
dispatchOptionsItemSelected(MenuItem item)372     public boolean dispatchOptionsItemSelected(MenuItem item) {
373         return mHost.mFragmentManager.dispatchOptionsItemSelected(item);
374     }
375 
376     /**
377      * Sends a context item selection event to the Fragments managed by the
378      * controller's FragmentManager. Once the event has been consumed,
379      * no additional handling will be performed.
380      * <p>Call immediately after an options menu item has been selected
381      *
382      * @return {@code true} if the context menu selection event was consumed
383      * @see Fragment#onContextItemSelected(MenuItem)
384      */
dispatchContextItemSelected(MenuItem item)385     public boolean dispatchContextItemSelected(MenuItem item) {
386         return mHost.mFragmentManager.dispatchContextItemSelected(item);
387     }
388 
389     /**
390      * Lets all Fragments managed by the controller's FragmentManager
391      * know their options menu has closed.
392      * <p>Call immediately after closing the Fragment's options menu.
393      *
394      * @see Fragment#onOptionsMenuClosed(Menu)
395      */
dispatchOptionsMenuClosed(Menu menu)396     public void dispatchOptionsMenuClosed(Menu menu) {
397         mHost.mFragmentManager.dispatchOptionsMenuClosed(menu);
398     }
399 
400     /**
401      * Execute any pending actions for the Fragments managed by the
402      * controller's FragmentManager.
403      * <p>Call when queued actions can be performed [eg when the
404      * Fragment moves into a start or resume state].
405      * @return {@code true} if queued actions were performed
406      */
execPendingActions()407     public boolean execPendingActions() {
408         return mHost.mFragmentManager.execPendingActions();
409     }
410 
411     /**
412      * Starts the loaders.
413      */
doLoaderStart()414     public void doLoaderStart() {
415         mHost.doLoaderStart();
416     }
417 
418     /**
419      * Stops the loaders, optionally retaining their state. This is useful for keeping the
420      * loader state across configuration changes.
421      *
422      * @param retain When {@code true}, the loaders aren't stopped, but, their instances
423      * are retained in a started state
424      */
doLoaderStop(boolean retain)425     public void doLoaderStop(boolean retain) {
426         mHost.doLoaderStop(retain);
427     }
428 
429     /**
430      * Destroys the loaders and, if their state is not being retained, removes them.
431      */
doLoaderDestroy()432     public void doLoaderDestroy() {
433         mHost.doLoaderDestroy();
434     }
435 
436     /**
437      * Lets the loaders know the host is ready to receive notifications.
438      */
reportLoaderStart()439     public void reportLoaderStart() {
440         mHost.reportLoaderStart();
441     }
442 
443     /**
444      * Returns a list of LoaderManagers that have opted to retain their instance across
445      * configuration changes.
446      */
retainLoaderNonConfig()447     public ArrayMap<String, LoaderManager> retainLoaderNonConfig() {
448         return mHost.retainLoaderNonConfig();
449     }
450 
451     /**
452      * Restores the saved state for all LoaderManagers. The given LoaderManager list are
453      * LoaderManager instances retained across configuration changes.
454      *
455      * @see #retainLoaderNonConfig()
456      */
restoreLoaderNonConfig(ArrayMap<String, LoaderManager> loaderManagers)457     public void restoreLoaderNonConfig(ArrayMap<String, LoaderManager> loaderManagers) {
458         mHost.restoreLoaderNonConfig(loaderManagers);
459     }
460 
461     /**
462      * Dumps the current state of the loaders.
463      */
dumpLoaders(String prefix, FileDescriptor fd, PrintWriter writer, String[] args)464     public void dumpLoaders(String prefix, FileDescriptor fd, PrintWriter writer, String[] args) {
465         mHost.dumpLoaders(prefix, fd, writer, args);
466     }
467 }
468