• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2016 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 package com.android.server.pm;
17 
18 import android.annotation.NonNull;
19 import android.content.pm.PackageInfo;
20 import android.util.Slog;
21 
22 import com.android.internal.util.Preconditions;
23 
24 import org.json.JSONException;
25 import org.json.JSONObject;
26 import org.xmlpull.v1.XmlPullParserException;
27 import org.xmlpull.v1.XmlSerializer;
28 
29 import java.io.IOException;
30 
31 /**
32  * All methods should be guarded by {@code #mShortcutUser.mService.mLock}.
33  */
34 abstract class ShortcutPackageItem {
35     private static final String TAG = ShortcutService.TAG;
36     private static final String KEY_NAME = "name";
37 
38     private final int mPackageUserId;
39     private final String mPackageName;
40 
41     private final ShortcutPackageInfo mPackageInfo;
42 
43     protected final ShortcutUser mShortcutUser;
44 
ShortcutPackageItem(@onNull ShortcutUser shortcutUser, int packageUserId, @NonNull String packageName, @NonNull ShortcutPackageInfo packageInfo)45     protected ShortcutPackageItem(@NonNull ShortcutUser shortcutUser,
46             int packageUserId, @NonNull String packageName,
47             @NonNull ShortcutPackageInfo packageInfo) {
48         mShortcutUser = shortcutUser;
49         mPackageUserId = packageUserId;
50         mPackageName = Preconditions.checkStringNotEmpty(packageName);
51         mPackageInfo = Preconditions.checkNotNull(packageInfo);
52     }
53 
getUser()54     public ShortcutUser getUser() {
55         return mShortcutUser;
56     }
57 
58     /**
59      * ID of the user who actually has this package running on.  For {@link ShortcutPackage},
60      * this is the same thing as {@link #getOwnerUserId}, but if it's a {@link ShortcutLauncher} and
61      * {@link #getOwnerUserId} is of a work profile, then this ID could be the user who owns the
62      * profile.
63      */
getPackageUserId()64     public int getPackageUserId() {
65         return mPackageUserId;
66     }
67 
68     /**
69      * ID of the user who sees the shortcuts from this instance.
70      */
getOwnerUserId()71     public abstract int getOwnerUserId();
72 
73     @NonNull
getPackageName()74     public String getPackageName() {
75         return mPackageName;
76     }
77 
getPackageInfo()78     public ShortcutPackageInfo getPackageInfo() {
79         return mPackageInfo;
80     }
81 
refreshPackageInfoAndSave()82     public void refreshPackageInfoAndSave() {
83         if (mPackageInfo.isShadow()) {
84             return; // Don't refresh for shadow user.
85         }
86         final ShortcutService s = mShortcutUser.mService;
87         mPackageInfo.refresh(s, this);
88         s.scheduleSaveUser(getOwnerUserId());
89     }
90 
attemptToRestoreIfNeededAndSave()91     public void attemptToRestoreIfNeededAndSave() {
92         if (!mPackageInfo.isShadow()) {
93             return; // Already installed, nothing to do.
94         }
95         final ShortcutService s = mShortcutUser.mService;
96         if (!s.isPackageInstalled(mPackageName, mPackageUserId)) {
97             if (ShortcutService.DEBUG) {
98                 Slog.d(TAG, String.format("Package still not installed: %s user=%d",
99                         mPackageName, mPackageUserId));
100             }
101             return; // Not installed, no need to restore yet.
102         }
103         if (!mPackageInfo.hasSignatures()) {
104             s.wtf("Attempted to restore package " + mPackageName + ", user=" + mPackageUserId
105                     + " but signatures not found in the restore data.");
106             onRestoreBlocked();
107             return;
108         }
109 
110         final PackageInfo pi = s.getPackageInfoWithSignatures(mPackageName, mPackageUserId);
111         if (!mPackageInfo.canRestoreTo(s, pi)) {
112             // Package is now installed, but can't restore.  Let the subclass do the cleanup.
113             onRestoreBlocked();
114             return;
115         }
116         if (ShortcutService.DEBUG) {
117             Slog.d(TAG, String.format("Restored package: %s/%d on user %d", mPackageName,
118                     mPackageUserId, getOwnerUserId()));
119         }
120 
121         onRestored();
122 
123         // Now the package is not shadow.
124         mPackageInfo.setShadow(false);
125 
126         s.scheduleSaveUser(mPackageUserId);
127     }
128 
129     /**
130      * Called when the new package can't be restored because it has a lower version number
131      * or different signatures.
132      */
onRestoreBlocked()133     protected abstract void onRestoreBlocked();
134 
135     /**
136      * Called when the new package is successfully restored.
137      */
onRestored()138     protected abstract void onRestored();
139 
saveToXml(@onNull XmlSerializer out, boolean forBackup)140     public abstract void saveToXml(@NonNull XmlSerializer out, boolean forBackup)
141             throws IOException, XmlPullParserException;
142 
dumpCheckin(boolean clear)143     public JSONObject dumpCheckin(boolean clear) throws JSONException {
144         final JSONObject result = new JSONObject();
145         result.put(KEY_NAME, mPackageName);
146         return result;
147     }
148 
149     /**
150      * Verify various internal states.
151      */
verifyStates()152     public void verifyStates() {
153     }
154 }
155