• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2020 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 com.android.server.am;
18 
19 import android.util.ArrayMap;
20 import android.util.TimeUtils;
21 
22 import com.android.internal.annotations.GuardedBy;
23 
24 import java.io.PrintWriter;
25 import java.util.ArrayList;
26 
27 /**
28  * The state info of all content providers in the process.
29  */
30 final class ProcessProviderRecord {
31     final ProcessRecord mApp;
32     private final ActivityManagerService mService;
33 
34     /**
35      * The last time someone else was using a provider in this process.
36      */
37     private long mLastProviderTime;
38 
39     /**
40      * class (String) -> ContentProviderRecord.
41      */
42     private final ArrayMap<String, ContentProviderRecord> mPubProviders = new ArrayMap<>();
43 
44     /**
45      * All ContentProviderRecord process is using.
46      */
47     private final ArrayList<ContentProviderConnection> mConProviders = new ArrayList<>();
48 
getLastProviderTime()49     long getLastProviderTime() {
50         return mLastProviderTime;
51     }
52 
setLastProviderTime(long lastProviderTime)53     void setLastProviderTime(long lastProviderTime) {
54         mLastProviderTime = lastProviderTime;
55     }
56 
hasProvider(String name)57     boolean hasProvider(String name) {
58         return mPubProviders.containsKey(name);
59     }
60 
getProvider(String name)61     ContentProviderRecord getProvider(String name) {
62         return mPubProviders.get(name);
63     }
64 
numberOfProviders()65     int numberOfProviders() {
66         return mPubProviders.size();
67     }
68 
getProviderAt(int index)69     ContentProviderRecord getProviderAt(int index) {
70         return mPubProviders.valueAt(index);
71     }
72 
installProvider(String name, ContentProviderRecord provider)73     void installProvider(String name, ContentProviderRecord provider) {
74         mPubProviders.put(name, provider);
75     }
76 
removeProvider(String name)77     void removeProvider(String name) {
78         mPubProviders.remove(name);
79     }
80 
ensureProviderCapacity(int capacity)81     void ensureProviderCapacity(int capacity) {
82         mPubProviders.ensureCapacity(capacity);
83     }
84 
numberOfProviderConnections()85     int numberOfProviderConnections() {
86         return mConProviders.size();
87     }
88 
getProviderConnectionAt(int index)89     ContentProviderConnection getProviderConnectionAt(int index) {
90         return mConProviders.get(index);
91     }
92 
addProviderConnection(ContentProviderConnection connection)93     void addProviderConnection(ContentProviderConnection connection) {
94         mConProviders.add(connection);
95     }
96 
removeProviderConnection(ContentProviderConnection connection)97     boolean removeProviderConnection(ContentProviderConnection connection) {
98         return mConProviders.remove(connection);
99     }
100 
ProcessProviderRecord(ProcessRecord app)101     ProcessProviderRecord(ProcessRecord app) {
102         mApp = app;
103         mService = app.mService;
104     }
105 
106     /**
107      * @return Should the process restart or not.
108      */
109     @GuardedBy("mService")
onCleanupApplicationRecordLocked(boolean allowRestart)110     boolean onCleanupApplicationRecordLocked(boolean allowRestart) {
111         boolean restart = false;
112         // Remove published content providers.
113         for (int i = mPubProviders.size() - 1; i >= 0; i--) {
114             final ContentProviderRecord cpr = mPubProviders.valueAt(i);
115             if (cpr.proc != mApp) {
116                 // If the hosting process record isn't really us, bail out
117                 continue;
118             }
119             final boolean alwaysRemove = mApp.mErrorState.isBad() || !allowRestart;
120             final boolean inLaunching = mService.mCpHelper
121                     .removeDyingProviderLocked(mApp, cpr, alwaysRemove);
122             if (!alwaysRemove && inLaunching && cpr.hasConnectionOrHandle()) {
123                 // We left the provider in the launching list, need to
124                 // restart it.
125                 restart = true;
126             }
127 
128             cpr.provider = null;
129             cpr.setProcess(null);
130         }
131         mPubProviders.clear();
132 
133         // Take care of any launching providers waiting for this process.
134         if (mService.mCpHelper.cleanupAppInLaunchingProvidersLocked(mApp, false)) {
135             mService.mProcessList.noteProcessDiedLocked(mApp);
136             restart = true;
137         }
138 
139         // Unregister from connected content providers.
140         if (!mConProviders.isEmpty()) {
141             for (int i = mConProviders.size() - 1; i >= 0; i--) {
142                 final ContentProviderConnection conn = mConProviders.get(i);
143                 conn.provider.connections.remove(conn);
144                 mService.stopAssociationLocked(mApp.uid, mApp.processName, conn.provider.uid,
145                         conn.provider.appInfo.longVersionCode, conn.provider.name,
146                         conn.provider.info.processName);
147             }
148             mConProviders.clear();
149         }
150 
151         return restart;
152     }
153 
dump(PrintWriter pw, String prefix, long nowUptime)154     void dump(PrintWriter pw, String prefix, long nowUptime) {
155         if (mLastProviderTime > 0) {
156             pw.print(prefix); pw.print("lastProviderTime=");
157             TimeUtils.formatDuration(mLastProviderTime, nowUptime, pw);
158             pw.println();
159         }
160         if (mPubProviders.size() > 0) {
161             pw.print(prefix); pw.println("Published Providers:");
162             for (int i = 0, size = mPubProviders.size(); i < size; i++) {
163                 pw.print(prefix); pw.print("  - "); pw.println(mPubProviders.keyAt(i));
164                 pw.print(prefix); pw.print("    -> "); pw.println(mPubProviders.valueAt(i));
165             }
166         }
167         if (mConProviders.size() > 0) {
168             pw.print(prefix); pw.println("Connected Providers:");
169             for (int i = 0, size = mConProviders.size(); i < size; i++) {
170                 pw.print(prefix); pw.print("  - ");
171                 pw.println(mConProviders.get(i).toShortString());
172             }
173         }
174     }
175 }
176