1 /*
2  * Copyright (C) 2017 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.content.Context;
20 import android.os.Bundle;
21 import android.os.Parcel;
22 import android.os.Parcelable;
23 import android.util.Log;
24 
25 final class FragmentState implements Parcelable {
26     final String mClassName;
27     final int mIndex;
28     final boolean mFromLayout;
29     final int mFragmentId;
30     final int mContainerId;
31     final String mTag;
32     final boolean mRetainInstance;
33     final boolean mDetached;
34     final Bundle mArguments;
35     final boolean mHidden;
36 
37     Bundle mSavedFragmentState;
38 
39     Fragment mInstance;
40 
FragmentState(Fragment frag)41     FragmentState(Fragment frag) {
42         mClassName = frag.getClass().getName();
43         mIndex = frag.mIndex;
44         mFromLayout = frag.mFromLayout;
45         mFragmentId = frag.mFragmentId;
46         mContainerId = frag.mContainerId;
47         mTag = frag.mTag;
48         mRetainInstance = frag.mRetainInstance;
49         mDetached = frag.mDetached;
50         mArguments = frag.mArguments;
51         mHidden = frag.mHidden;
52     }
53 
FragmentState(Parcel in)54     FragmentState(Parcel in) {
55         mClassName = in.readString();
56         mIndex = in.readInt();
57         mFromLayout = in.readInt() != 0;
58         mFragmentId = in.readInt();
59         mContainerId = in.readInt();
60         mTag = in.readString();
61         mRetainInstance = in.readInt() != 0;
62         mDetached = in.readInt() != 0;
63         mArguments = in.readBundle();
64         mHidden = in.readInt() != 0;
65         mSavedFragmentState = in.readBundle();
66     }
67 
instantiate(FragmentHostCallback host, FragmentContainer container, Fragment parent, FragmentManagerNonConfig childNonConfig)68     public Fragment instantiate(FragmentHostCallback host, FragmentContainer container,
69             Fragment parent, FragmentManagerNonConfig childNonConfig) {
70         if (mInstance == null) {
71             final Context context = host.getContext();
72             if (mArguments != null) {
73                 mArguments.setClassLoader(context.getClassLoader());
74             }
75 
76             if (container != null) {
77                 mInstance = container.instantiate(context, mClassName, mArguments);
78             } else {
79                 mInstance = Fragment.instantiate(context, mClassName, mArguments);
80             }
81 
82             if (mSavedFragmentState != null) {
83                 mSavedFragmentState.setClassLoader(context.getClassLoader());
84                 mInstance.mSavedFragmentState = mSavedFragmentState;
85             }
86             mInstance.setIndex(mIndex, parent);
87             mInstance.mFromLayout = mFromLayout;
88             mInstance.mRestored = true;
89             mInstance.mFragmentId = mFragmentId;
90             mInstance.mContainerId = mContainerId;
91             mInstance.mTag = mTag;
92             mInstance.mRetainInstance = mRetainInstance;
93             mInstance.mDetached = mDetached;
94             mInstance.mHidden = mHidden;
95             mInstance.mFragmentManager = host.mFragmentManager;
96 
97             if (FragmentManagerImpl.DEBUG) {
98                 Log.v(FragmentManagerImpl.TAG, "Instantiated fragment " + mInstance);
99             }
100         }
101         mInstance.mChildNonConfig = childNonConfig;
102         return mInstance;
103     }
104 
105     @Override
describeContents()106     public int describeContents() {
107         return 0;
108     }
109 
110     @Override
writeToParcel(Parcel dest, int flags)111     public void writeToParcel(Parcel dest, int flags) {
112         dest.writeString(mClassName);
113         dest.writeInt(mIndex);
114         dest.writeInt(mFromLayout ? 1 : 0);
115         dest.writeInt(mFragmentId);
116         dest.writeInt(mContainerId);
117         dest.writeString(mTag);
118         dest.writeInt(mRetainInstance ? 1 : 0);
119         dest.writeInt(mDetached ? 1 : 0);
120         dest.writeBundle(mArguments);
121         dest.writeInt(mHidden ? 1 : 0);
122         dest.writeBundle(mSavedFragmentState);
123     }
124 
125     public static final @android.annotation.NonNull Parcelable.Creator<FragmentState> CREATOR =
126             new Parcelable.Creator<FragmentState>() {
127                 @Override
128                 public FragmentState createFromParcel(Parcel in) {
129                     return new FragmentState(in);
130                 }
131 
132                 @Override
133                 public FragmentState[] newArray(int size) {
134                     return new FragmentState[size];
135                 }
136             };
137 }