10acbb14574d859b5f1cc0b7c6bbdfbeba38f3e55Makoto Onuki/* 20acbb14574d859b5f1cc0b7c6bbdfbeba38f3e55Makoto Onuki * Copyright (C) 2016 The Android Open Source Project 30acbb14574d859b5f1cc0b7c6bbdfbeba38f3e55Makoto Onuki * 40acbb14574d859b5f1cc0b7c6bbdfbeba38f3e55Makoto Onuki * Licensed under the Apache License, Version 2.0 (the "License"); 50acbb14574d859b5f1cc0b7c6bbdfbeba38f3e55Makoto Onuki * you may not use this file except in compliance with the License. 60acbb14574d859b5f1cc0b7c6bbdfbeba38f3e55Makoto Onuki * You may obtain a copy of the License at 70acbb14574d859b5f1cc0b7c6bbdfbeba38f3e55Makoto Onuki * 80acbb14574d859b5f1cc0b7c6bbdfbeba38f3e55Makoto Onuki * http://www.apache.org/licenses/LICENSE-2.0 90acbb14574d859b5f1cc0b7c6bbdfbeba38f3e55Makoto Onuki * 100acbb14574d859b5f1cc0b7c6bbdfbeba38f3e55Makoto Onuki * Unless required by applicable law or agreed to in writing, software 110acbb14574d859b5f1cc0b7c6bbdfbeba38f3e55Makoto Onuki * distributed under the License is distributed on an "AS IS" BASIS, 120acbb14574d859b5f1cc0b7c6bbdfbeba38f3e55Makoto Onuki * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 130acbb14574d859b5f1cc0b7c6bbdfbeba38f3e55Makoto Onuki * See the License for the specific language governing permissions and 140acbb14574d859b5f1cc0b7c6bbdfbeba38f3e55Makoto Onuki * limitations under the License. 150acbb14574d859b5f1cc0b7c6bbdfbeba38f3e55Makoto Onuki */ 160acbb14574d859b5f1cc0b7c6bbdfbeba38f3e55Makoto Onukipackage com.android.server.pm; 170acbb14574d859b5f1cc0b7c6bbdfbeba38f3e55Makoto Onuki 180acbb14574d859b5f1cc0b7c6bbdfbeba38f3e55Makoto Onukiimport android.annotation.NonNull; 192e210c4d0f766e52ea4c087a1d54213c36a4e0eaMakoto Onukiimport android.content.pm.PackageInfo; 20a4f89b1251235a7373996d0dda0d888673d8e941Makoto Onukiimport android.content.pm.ShortcutInfo; 212e210c4d0f766e52ea4c087a1d54213c36a4e0eaMakoto Onukiimport android.util.Slog; 220acbb14574d859b5f1cc0b7c6bbdfbeba38f3e55Makoto Onuki 239da23fc6ac565b38129d52f4f8f174c833a9bd01Makoto Onukiimport com.android.internal.util.Preconditions; 249da23fc6ac565b38129d52f4f8f174c833a9bd01Makoto Onuki 2576269928e677725e2d9b28e2e3aa79961a60a1d0Makoto Onukiimport org.json.JSONException; 2676269928e677725e2d9b28e2e3aa79961a60a1d0Makoto Onukiimport org.json.JSONObject; 270acbb14574d859b5f1cc0b7c6bbdfbeba38f3e55Makoto Onukiimport org.xmlpull.v1.XmlPullParserException; 280acbb14574d859b5f1cc0b7c6bbdfbeba38f3e55Makoto Onukiimport org.xmlpull.v1.XmlSerializer; 290acbb14574d859b5f1cc0b7c6bbdfbeba38f3e55Makoto Onuki 300acbb14574d859b5f1cc0b7c6bbdfbeba38f3e55Makoto Onukiimport java.io.IOException; 310acbb14574d859b5f1cc0b7c6bbdfbeba38f3e55Makoto Onuki 3222fcc68e6be0edaa98f3dacf79d580a5e5d50005Makoto Onuki/** 3322fcc68e6be0edaa98f3dacf79d580a5e5d50005Makoto Onuki * All methods should be guarded by {@code #mShortcutUser.mService.mLock}. 3422fcc68e6be0edaa98f3dacf79d580a5e5d50005Makoto Onuki */ 359da23fc6ac565b38129d52f4f8f174c833a9bd01Makoto Onukiabstract class ShortcutPackageItem { 362e210c4d0f766e52ea4c087a1d54213c36a4e0eaMakoto Onuki private static final String TAG = ShortcutService.TAG; 3776269928e677725e2d9b28e2e3aa79961a60a1d0Makoto Onuki private static final String KEY_NAME = "name"; 382e210c4d0f766e52ea4c087a1d54213c36a4e0eaMakoto Onuki 399da23fc6ac565b38129d52f4f8f174c833a9bd01Makoto Onuki private final int mPackageUserId; 409da23fc6ac565b38129d52f4f8f174c833a9bd01Makoto Onuki private final String mPackageName; 419da23fc6ac565b38129d52f4f8f174c833a9bd01Makoto Onuki 422e210c4d0f766e52ea4c087a1d54213c36a4e0eaMakoto Onuki private final ShortcutPackageInfo mPackageInfo; 439da23fc6ac565b38129d52f4f8f174c833a9bd01Makoto Onuki 44fc4cf2da34335fd7e84c020f51eea1a341d3f134Makoto Onuki protected ShortcutUser mShortcutUser; 454d36b3a8c5ba1289d851ef337e46709bba333100Makoto Onuki 464d36b3a8c5ba1289d851ef337e46709bba333100Makoto Onuki protected ShortcutPackageItem(@NonNull ShortcutUser shortcutUser, 474d36b3a8c5ba1289d851ef337e46709bba333100Makoto Onuki int packageUserId, @NonNull String packageName, 489da23fc6ac565b38129d52f4f8f174c833a9bd01Makoto Onuki @NonNull ShortcutPackageInfo packageInfo) { 494d36b3a8c5ba1289d851ef337e46709bba333100Makoto Onuki mShortcutUser = shortcutUser; 509da23fc6ac565b38129d52f4f8f174c833a9bd01Makoto Onuki mPackageUserId = packageUserId; 519da23fc6ac565b38129d52f4f8f174c833a9bd01Makoto Onuki mPackageName = Preconditions.checkStringNotEmpty(packageName); 529da23fc6ac565b38129d52f4f8f174c833a9bd01Makoto Onuki mPackageInfo = Preconditions.checkNotNull(packageInfo); 539da23fc6ac565b38129d52f4f8f174c833a9bd01Makoto Onuki } 549da23fc6ac565b38129d52f4f8f174c833a9bd01Makoto Onuki 55fc4cf2da34335fd7e84c020f51eea1a341d3f134Makoto Onuki /** 56fc4cf2da34335fd7e84c020f51eea1a341d3f134Makoto Onuki * Change the parent {@link ShortcutUser}. Need it in the restore code. 57fc4cf2da34335fd7e84c020f51eea1a341d3f134Makoto Onuki */ 58fc4cf2da34335fd7e84c020f51eea1a341d3f134Makoto Onuki public void replaceUser(ShortcutUser user) { 59fc4cf2da34335fd7e84c020f51eea1a341d3f134Makoto Onuki mShortcutUser = user; 60fc4cf2da34335fd7e84c020f51eea1a341d3f134Makoto Onuki } 61fc4cf2da34335fd7e84c020f51eea1a341d3f134Makoto Onuki 624e6cef49ef11bbb5bfc0e9f0fb865188492d88b0Makoto Onuki public ShortcutUser getUser() { 634e6cef49ef11bbb5bfc0e9f0fb865188492d88b0Makoto Onuki return mShortcutUser; 644e6cef49ef11bbb5bfc0e9f0fb865188492d88b0Makoto Onuki } 654e6cef49ef11bbb5bfc0e9f0fb865188492d88b0Makoto Onuki 669da23fc6ac565b38129d52f4f8f174c833a9bd01Makoto Onuki /** 679da23fc6ac565b38129d52f4f8f174c833a9bd01Makoto Onuki * ID of the user who actually has this package running on. For {@link ShortcutPackage}, 689da23fc6ac565b38129d52f4f8f174c833a9bd01Makoto Onuki * this is the same thing as {@link #getOwnerUserId}, but if it's a {@link ShortcutLauncher} and 69c8c3329dd918b8ea16d6317d19ddee12325800f3Makoto Onuki * {@link #getOwnerUserId} is of work profile, then this ID is of the primary user. 709da23fc6ac565b38129d52f4f8f174c833a9bd01Makoto Onuki */ 719da23fc6ac565b38129d52f4f8f174c833a9bd01Makoto Onuki public int getPackageUserId() { 729da23fc6ac565b38129d52f4f8f174c833a9bd01Makoto Onuki return mPackageUserId; 739da23fc6ac565b38129d52f4f8f174c833a9bd01Makoto Onuki } 749da23fc6ac565b38129d52f4f8f174c833a9bd01Makoto Onuki 759da23fc6ac565b38129d52f4f8f174c833a9bd01Makoto Onuki /** 769da23fc6ac565b38129d52f4f8f174c833a9bd01Makoto Onuki * ID of the user who sees the shortcuts from this instance. 779da23fc6ac565b38129d52f4f8f174c833a9bd01Makoto Onuki */ 789da23fc6ac565b38129d52f4f8f174c833a9bd01Makoto Onuki public abstract int getOwnerUserId(); 799da23fc6ac565b38129d52f4f8f174c833a9bd01Makoto Onuki 800acbb14574d859b5f1cc0b7c6bbdfbeba38f3e55Makoto Onuki @NonNull 819da23fc6ac565b38129d52f4f8f174c833a9bd01Makoto Onuki public String getPackageName() { 829da23fc6ac565b38129d52f4f8f174c833a9bd01Makoto Onuki return mPackageName; 839da23fc6ac565b38129d52f4f8f174c833a9bd01Makoto Onuki } 849da23fc6ac565b38129d52f4f8f174c833a9bd01Makoto Onuki 859da23fc6ac565b38129d52f4f8f174c833a9bd01Makoto Onuki public ShortcutPackageInfo getPackageInfo() { 869da23fc6ac565b38129d52f4f8f174c833a9bd01Makoto Onuki return mPackageInfo; 879da23fc6ac565b38129d52f4f8f174c833a9bd01Makoto Onuki } 889da23fc6ac565b38129d52f4f8f174c833a9bd01Makoto Onuki 89c8c3329dd918b8ea16d6317d19ddee12325800f3Makoto Onuki public void refreshPackageSignatureAndSave() { 902e210c4d0f766e52ea4c087a1d54213c36a4e0eaMakoto Onuki if (mPackageInfo.isShadow()) { 912e210c4d0f766e52ea4c087a1d54213c36a4e0eaMakoto Onuki return; // Don't refresh for shadow user. 922e210c4d0f766e52ea4c087a1d54213c36a4e0eaMakoto Onuki } 93c51b2876ec5c0af449469a0f76bb38c51cfcff04Makoto Onuki final ShortcutService s = mShortcutUser.mService; 94c8c3329dd918b8ea16d6317d19ddee12325800f3Makoto Onuki mPackageInfo.refreshSignature(s, this); 959da23fc6ac565b38129d52f4f8f174c833a9bd01Makoto Onuki s.scheduleSaveUser(getOwnerUserId()); 969da23fc6ac565b38129d52f4f8f174c833a9bd01Makoto Onuki } 979da23fc6ac565b38129d52f4f8f174c833a9bd01Makoto Onuki 98c51b2876ec5c0af449469a0f76bb38c51cfcff04Makoto Onuki public void attemptToRestoreIfNeededAndSave() { 992e210c4d0f766e52ea4c087a1d54213c36a4e0eaMakoto Onuki if (!mPackageInfo.isShadow()) { 1002e210c4d0f766e52ea4c087a1d54213c36a4e0eaMakoto Onuki return; // Already installed, nothing to do. 1019da23fc6ac565b38129d52f4f8f174c833a9bd01Makoto Onuki } 102c51b2876ec5c0af449469a0f76bb38c51cfcff04Makoto Onuki final ShortcutService s = mShortcutUser.mService; 1032e210c4d0f766e52ea4c087a1d54213c36a4e0eaMakoto Onuki if (!s.isPackageInstalled(mPackageName, mPackageUserId)) { 1042e210c4d0f766e52ea4c087a1d54213c36a4e0eaMakoto Onuki if (ShortcutService.DEBUG) { 105a4f89b1251235a7373996d0dda0d888673d8e941Makoto Onuki Slog.d(TAG, String.format("Package still not installed: %s/u%d", 1062e210c4d0f766e52ea4c087a1d54213c36a4e0eaMakoto Onuki mPackageName, mPackageUserId)); 1072e210c4d0f766e52ea4c087a1d54213c36a4e0eaMakoto Onuki } 1082e210c4d0f766e52ea4c087a1d54213c36a4e0eaMakoto Onuki return; // Not installed, no need to restore yet. 1092e210c4d0f766e52ea4c087a1d54213c36a4e0eaMakoto Onuki } 110a4f89b1251235a7373996d0dda0d888673d8e941Makoto Onuki int restoreBlockReason; 1113accca05ddcad9d0b1b313eae49f273e39121d3cDianne Hackborn long currentVersionCode = ShortcutInfo.VERSION_CODE_UNKNOWN; 112a4f89b1251235a7373996d0dda0d888673d8e941Makoto Onuki 1132e210c4d0f766e52ea4c087a1d54213c36a4e0eaMakoto Onuki if (!mPackageInfo.hasSignatures()) { 114a4f89b1251235a7373996d0dda0d888673d8e941Makoto Onuki s.wtf("Attempted to restore package " + mPackageName + "/u" + mPackageUserId 1152e210c4d0f766e52ea4c087a1d54213c36a4e0eaMakoto Onuki + " but signatures not found in the restore data."); 116a4f89b1251235a7373996d0dda0d888673d8e941Makoto Onuki restoreBlockReason = ShortcutInfo.DISABLED_REASON_SIGNATURE_MISMATCH; 117a4f89b1251235a7373996d0dda0d888673d8e941Makoto Onuki } else { 118fac592f64c55004e9048e30e03d6dc65bdb4f00aMakoto Onuki final PackageInfo pi = s.getPackageInfoWithSignatures(mPackageName, mPackageUserId); 1193accca05ddcad9d0b1b313eae49f273e39121d3cDianne Hackborn currentVersionCode = pi.getLongVersionCode(); 120a4f89b1251235a7373996d0dda0d888673d8e941Makoto Onuki restoreBlockReason = mPackageInfo.canRestoreTo(s, pi, canRestoreAnyVersion()); 1212e210c4d0f766e52ea4c087a1d54213c36a4e0eaMakoto Onuki } 1222e210c4d0f766e52ea4c087a1d54213c36a4e0eaMakoto Onuki 123a4f89b1251235a7373996d0dda0d888673d8e941Makoto Onuki if (ShortcutService.DEBUG) { 124a4f89b1251235a7373996d0dda0d888673d8e941Makoto Onuki Slog.d(TAG, String.format("Restoring package: %s/u%d (version=%d) %s for u%d", 125a4f89b1251235a7373996d0dda0d888673d8e941Makoto Onuki mPackageName, mPackageUserId, currentVersionCode, 126b1588c0d3955a8574c3ae588568b2c393c7b5665Makoto Onuki ShortcutInfo.getDisabledReasonDebugString(restoreBlockReason), 127a4f89b1251235a7373996d0dda0d888673d8e941Makoto Onuki getOwnerUserId())); 128fac592f64c55004e9048e30e03d6dc65bdb4f00aMakoto Onuki } 1292e210c4d0f766e52ea4c087a1d54213c36a4e0eaMakoto Onuki 130a4f89b1251235a7373996d0dda0d888673d8e941Makoto Onuki onRestored(restoreBlockReason); 131a4f89b1251235a7373996d0dda0d888673d8e941Makoto Onuki 132fac592f64c55004e9048e30e03d6dc65bdb4f00aMakoto Onuki // Either way, it's no longer a shadow. 1332e210c4d0f766e52ea4c087a1d54213c36a4e0eaMakoto Onuki mPackageInfo.setShadow(false); 1342e210c4d0f766e52ea4c087a1d54213c36a4e0eaMakoto Onuki 1352e210c4d0f766e52ea4c087a1d54213c36a4e0eaMakoto Onuki s.scheduleSaveUser(mPackageUserId); 1369da23fc6ac565b38129d52f4f8f174c833a9bd01Makoto Onuki } 1370acbb14574d859b5f1cc0b7c6bbdfbeba38f3e55Makoto Onuki 138a4f89b1251235a7373996d0dda0d888673d8e941Makoto Onuki protected abstract boolean canRestoreAnyVersion(); 1392e210c4d0f766e52ea4c087a1d54213c36a4e0eaMakoto Onuki 140a4f89b1251235a7373996d0dda0d888673d8e941Makoto Onuki protected abstract void onRestored(int restoreBlockReason); 1412e210c4d0f766e52ea4c087a1d54213c36a4e0eaMakoto Onuki 1429da23fc6ac565b38129d52f4f8f174c833a9bd01Makoto Onuki public abstract void saveToXml(@NonNull XmlSerializer out, boolean forBackup) 1430acbb14574d859b5f1cc0b7c6bbdfbeba38f3e55Makoto Onuki throws IOException, XmlPullParserException; 1447001a6154088c87a31d56641762ff0c2a48f1d57Makoto Onuki 14576269928e677725e2d9b28e2e3aa79961a60a1d0Makoto Onuki public JSONObject dumpCheckin(boolean clear) throws JSONException { 14676269928e677725e2d9b28e2e3aa79961a60a1d0Makoto Onuki final JSONObject result = new JSONObject(); 14776269928e677725e2d9b28e2e3aa79961a60a1d0Makoto Onuki result.put(KEY_NAME, mPackageName); 14876269928e677725e2d9b28e2e3aa79961a60a1d0Makoto Onuki return result; 14976269928e677725e2d9b28e2e3aa79961a60a1d0Makoto Onuki } 15076269928e677725e2d9b28e2e3aa79961a60a1d0Makoto Onuki 1517001a6154088c87a31d56641762ff0c2a48f1d57Makoto Onuki /** 1527001a6154088c87a31d56641762ff0c2a48f1d57Makoto Onuki * Verify various internal states. 1537001a6154088c87a31d56641762ff0c2a48f1d57Makoto Onuki */ 1547001a6154088c87a31d56641762ff0c2a48f1d57Makoto Onuki public void verifyStates() { 1557001a6154088c87a31d56641762ff0c2a48f1d57Makoto Onuki } 1560acbb14574d859b5f1cc0b7c6bbdfbeba38f3e55Makoto Onuki} 157