1 /* 2 * Copyright (C) 2021 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.pm.pkg; 18 19 import android.annotation.Nullable; 20 import android.content.pm.SuspendDialogInfo; 21 import android.os.BaseBundle; 22 import android.os.PersistableBundle; 23 import android.util.Slog; 24 25 import com.android.modules.utils.TypedXmlPullParser; 26 import com.android.modules.utils.TypedXmlSerializer; 27 28 import org.xmlpull.v1.XmlPullParser; 29 import org.xmlpull.v1.XmlPullParserException; 30 import org.xmlpull.v1.XmlSerializer; 31 32 import java.io.IOException; 33 import java.util.Objects; 34 35 /** 36 * Container to describe suspension parameters. 37 * @hide 38 */ 39 public final class SuspendParams { 40 41 private static final String LOG_TAG = "FrameworkPackageUserState"; 42 private static final String TAG_DIALOG_INFO = "dialog-info"; 43 private static final String TAG_APP_EXTRAS = "app-extras"; 44 private static final String TAG_LAUNCHER_EXTRAS = "launcher-extras"; 45 private static final String ATTR_QUARANTINED = "quarantined"; 46 47 private final SuspendDialogInfo mDialogInfo; 48 private final PersistableBundle mAppExtras; 49 private final PersistableBundle mLauncherExtras; 50 51 private final boolean mQuarantined; 52 SuspendParams(SuspendDialogInfo dialogInfo, PersistableBundle appExtras, PersistableBundle launcherExtras)53 public SuspendParams(SuspendDialogInfo dialogInfo, PersistableBundle appExtras, 54 PersistableBundle launcherExtras) { 55 this(dialogInfo, appExtras, launcherExtras, false /* quarantined */); 56 } 57 SuspendParams(SuspendDialogInfo dialogInfo, PersistableBundle appExtras, PersistableBundle launcherExtras, boolean quarantined)58 public SuspendParams(SuspendDialogInfo dialogInfo, PersistableBundle appExtras, 59 PersistableBundle launcherExtras, boolean quarantined) { 60 this.mDialogInfo = dialogInfo; 61 this.mAppExtras = appExtras; 62 this.mLauncherExtras = launcherExtras; 63 this.mQuarantined = quarantined; 64 } 65 66 @Override equals(@ullable Object obj)67 public boolean equals(@Nullable Object obj) { 68 if (this == obj) { 69 return true; 70 } 71 if (!(obj instanceof SuspendParams)) { 72 return false; 73 } 74 final SuspendParams other = (SuspendParams) obj; 75 if (!Objects.equals(mDialogInfo, other.mDialogInfo)) { 76 return false; 77 } 78 if (!BaseBundle.kindofEquals(mAppExtras, other.mAppExtras)) { 79 return false; 80 } 81 if (!BaseBundle.kindofEquals(mLauncherExtras, other.mLauncherExtras)) { 82 return false; 83 } 84 if (mQuarantined != other.mQuarantined) { 85 return false; 86 } 87 return true; 88 } 89 90 @Override hashCode()91 public int hashCode() { 92 int hashCode = Objects.hashCode(mDialogInfo); 93 hashCode = 31 * hashCode + ((mAppExtras != null) ? mAppExtras.size() : 0); 94 hashCode = 31 * hashCode + ((mLauncherExtras != null) ? mLauncherExtras.size() : 0); 95 hashCode = 31 * hashCode + Boolean.hashCode(mQuarantined); 96 return hashCode; 97 } 98 99 /** 100 * Serializes this object into an xml format 101 * 102 * @param out the {@link XmlSerializer} object 103 */ saveToXml(TypedXmlSerializer out)104 public void saveToXml(TypedXmlSerializer out) throws IOException { 105 out.attributeBoolean(null, ATTR_QUARANTINED, mQuarantined); 106 if (mDialogInfo != null) { 107 out.startTag(null, TAG_DIALOG_INFO); 108 mDialogInfo.saveToXml(out); 109 out.endTag(null, TAG_DIALOG_INFO); 110 } 111 if (mAppExtras != null) { 112 out.startTag(null, TAG_APP_EXTRAS); 113 try { 114 mAppExtras.saveToXml(out); 115 } catch (XmlPullParserException e) { 116 Slog.e(LOG_TAG, "Exception while trying to write appExtras." 117 + " Will be lost on reboot", e); 118 } 119 out.endTag(null, TAG_APP_EXTRAS); 120 } 121 if (mLauncherExtras != null) { 122 out.startTag(null, TAG_LAUNCHER_EXTRAS); 123 try { 124 mLauncherExtras.saveToXml(out); 125 } catch (XmlPullParserException e) { 126 Slog.e(LOG_TAG, "Exception while trying to write launcherExtras." 127 + " Will be lost on reboot", e); 128 } 129 out.endTag(null, TAG_LAUNCHER_EXTRAS); 130 } 131 } 132 133 /** 134 * Parses this object from the xml format. Returns {@code null} if no object related 135 * information could be read. 136 * 137 * @param in the reader 138 */ restoreFromXml(TypedXmlPullParser in)139 public static SuspendParams restoreFromXml(TypedXmlPullParser in) throws IOException { 140 SuspendDialogInfo readDialogInfo = null; 141 PersistableBundle readAppExtras = null; 142 PersistableBundle readLauncherExtras = null; 143 144 final boolean quarantined = in.getAttributeBoolean(null, ATTR_QUARANTINED, false); 145 146 final int currentDepth = in.getDepth(); 147 int type; 148 try { 149 while ((type = in.next()) != XmlPullParser.END_DOCUMENT 150 && (type != XmlPullParser.END_TAG 151 || in.getDepth() > currentDepth)) { 152 if (type == XmlPullParser.END_TAG 153 || type == XmlPullParser.TEXT) { 154 continue; 155 } 156 switch (in.getName()) { 157 case TAG_DIALOG_INFO: 158 readDialogInfo = SuspendDialogInfo.restoreFromXml(in); 159 break; 160 case TAG_APP_EXTRAS: 161 readAppExtras = PersistableBundle.restoreFromXml(in); 162 break; 163 case TAG_LAUNCHER_EXTRAS: 164 readLauncherExtras = PersistableBundle.restoreFromXml(in); 165 break; 166 default: 167 Slog.w(LOG_TAG, "Unknown tag " + in.getName() 168 + " in SuspendParams. Ignoring"); 169 break; 170 } 171 } 172 } catch (XmlPullParserException e) { 173 Slog.e(LOG_TAG, "Exception while trying to parse SuspendParams," 174 + " some fields may default", e); 175 } 176 return new SuspendParams(readDialogInfo, readAppExtras, readLauncherExtras, quarantined); 177 } 178 getDialogInfo()179 public SuspendDialogInfo getDialogInfo() { 180 return mDialogInfo; 181 } 182 getAppExtras()183 public PersistableBundle getAppExtras() { 184 return mAppExtras; 185 } 186 getLauncherExtras()187 public PersistableBundle getLauncherExtras() { 188 return mLauncherExtras; 189 } 190 isQuarantined()191 public boolean isQuarantined() { 192 return mQuarantined; 193 } 194 } 195