diff options
5 files changed, 391 insertions, 88 deletions
diff --git a/core/java/android/service/notification/ZenModeConfig.java b/core/java/android/service/notification/ZenModeConfig.java index e819c963ae45..5012d77568bf 100644 --- a/core/java/android/service/notification/ZenModeConfig.java +++ b/core/java/android/service/notification/ZenModeConfig.java @@ -146,6 +146,7 @@ public class ZenModeConfig implements Parcelable { private static final String RULE_ATT_CONDITION_ID = "conditionId"; private static final String RULE_ATT_CREATION_TIME = "creationTime"; private static final String RULE_ATT_ENABLER = "enabler"; + private static final String RULE_ATT_MODIFIED = "modified"; @UnsupportedAppUsage public boolean allowAlarms = DEFAULT_ALLOW_ALARMS; @@ -633,6 +634,7 @@ public class ZenModeConfig implements Parcelable { Slog.i(TAG, "Updating zenMode of automatic rule " + rt.name); rt.zenMode = Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS; } + rt.modified = safeBoolean(parser, RULE_ATT_MODIFIED, false); return rt; } @@ -656,6 +658,7 @@ public class ZenModeConfig implements Parcelable { if (rule.condition != null) { writeConditionXml(rule.condition, out); } + out.attribute(null, RULE_ATT_MODIFIED, Boolean.toString(rule.modified)); } public static Condition readConditionXml(XmlPullParser parser) { @@ -1456,6 +1459,7 @@ public class ZenModeConfig implements Parcelable { public long creationTime; // required for automatic public String enabler; // package name, only used for manual rules. public ZenPolicy zenPolicy; + public boolean modified; // rule has been modified from initial creation public ZenRule() { } @@ -1477,6 +1481,7 @@ public class ZenModeConfig implements Parcelable { enabler = source.readString(); } zenPolicy = source.readParcelable(null); + modified = source.readInt() == 1; } @Override @@ -1512,6 +1517,7 @@ public class ZenModeConfig implements Parcelable { dest.writeInt(0); } dest.writeParcelable(zenPolicy, 0); + dest.writeInt(modified ? 1 : 0); } @Override @@ -1528,6 +1534,7 @@ public class ZenModeConfig implements Parcelable { .append(",creationTime=").append(creationTime) .append(",enabler=").append(enabler) .append(",zenPolicy=").append(zenPolicy) + .append(",modified=").append(modified) .append(']').toString(); } @@ -1554,6 +1561,7 @@ public class ZenModeConfig implements Parcelable { if (zenPolicy != null) { zenPolicy.writeToProto(proto, ZenRuleProto.ZEN_POLICY); } + proto.write(ZenRuleProto.MODIFIED, modified); proto.end(token); } @@ -1606,6 +1614,9 @@ public class ZenModeConfig implements Parcelable { if (!Objects.equals(zenPolicy, to.zenPolicy)) { d.addLine(item, "zenPolicy", zenPolicy, to.zenPolicy); } + if (modified != to.modified) { + d.addLine(item, "modified", modified, to.modified); + } } @Override @@ -1622,13 +1633,14 @@ public class ZenModeConfig implements Parcelable { && Objects.equals(other.component, component) && Objects.equals(other.id, id) && Objects.equals(other.enabler, enabler) - && Objects.equals(other.zenPolicy, zenPolicy); + && Objects.equals(other.zenPolicy, zenPolicy) + && other.modified == modified; } @Override public int hashCode() { return Objects.hash(enabled, snoozing, name, zenMode, conditionId, condition, - component, id, enabler, zenPolicy); + component, id, enabler, zenPolicy, modified); } public boolean isAutomaticActive() { diff --git a/core/proto/android/service/notification.proto b/core/proto/android/service/notification.proto index 8836c2e4241f..c08d7cafd9cc 100644 --- a/core/proto/android/service/notification.proto +++ b/core/proto/android/service/notification.proto @@ -201,6 +201,9 @@ message ZenRuleProto { optional ConditionProto condition = 9; optional android.content.ComponentNameProto component = 10; optional ZenPolicyProto zenPolicy = 11; + + // Indicates whether this ZenRule has been modified after its initial creation + optional bool modified = 12 [ (android.privacy).dest = DEST_AUTOMATIC ]; } // A dump from com.android.server.notification.ZenModeHelper. diff --git a/core/res/res/xml/default_zen_mode_config.xml b/core/res/res/xml/default_zen_mode_config.xml index cb4e5c46b73e..6cf6a8273f5f 100644 --- a/core/res/res/xml/default_zen_mode_config.xml +++ b/core/res/res/xml/default_zen_mode_config.xml @@ -18,13 +18,17 @@ --> <!-- Default configuration for zen mode. See android.service.notification.ZenModeConfig. --> -<zen version="7"> +<zen version="8"> <allow alarms="true" media="true" system="false" calls="true" callsFrom="2" messages="false" reminders="false" events="false" repeatCallers="true" /> - + <automatic ruleId="EVENTS_DEFAULT_RULE" enabled="false" snoozing="false" name="Event" zen="1" + component="android/com.android.server.notification.EventConditionProvider" + conditionId="condition://android/event?userId=-10000&calendar=&reply=1"/> + <automatic ruleId="EVERY_NIGHT_DEFAULT_RULE" enabled="false" snoozing="false" name="Sleeping" + zen="1" component="android/com.android.server.notification.ScheduleConditionProvider" + conditionId="condition://android/schedule?days=1.2.3.4.5.6.7&start=22.0&end=7.0&exitAtAlarm=true"/> <!-- all visual effects that exist as of P --> <disallow visualEffects="511" /> - <!-- whether there are notification channels that can bypass dnd --> <state areChannelsBypassingDnd="false" /> </zen> diff --git a/services/core/java/com/android/server/notification/ZenModeHelper.java b/services/core/java/com/android/server/notification/ZenModeHelper.java index 4dd2bf25ed67..25f52e7a8501 100644 --- a/services/core/java/com/android/server/notification/ZenModeHelper.java +++ b/services/core/java/com/android/server/notification/ZenModeHelper.java @@ -52,8 +52,6 @@ import android.provider.Settings.Global; import android.service.notification.Condition; import android.service.notification.ConditionProviderService; import android.service.notification.ZenModeConfig; -import android.service.notification.ZenModeConfig.EventInfo; -import android.service.notification.ZenModeConfig.ScheduleInfo; import android.service.notification.ZenModeConfig.ZenRule; import android.service.notification.ZenModeProto; import android.util.AndroidRuntimeException; @@ -119,8 +117,6 @@ public class ZenModeHelper { public static final long SUPPRESSED_EFFECT_ALL = SUPPRESSED_EFFECT_CALLS | SUPPRESSED_EFFECT_NOTIFICATIONS; - protected String mDefaultRuleEveryNightName; - protected String mDefaultRuleEventsName; @VisibleForTesting protected boolean mIsBootComplete; public ZenModeHelper(Context context, Looper looper, ConditionProviders conditionProviders) { @@ -130,9 +126,9 @@ public class ZenModeHelper { mAppOps = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE); mNotificationManager = context.getSystemService(NotificationManager.class); - mDefaultConfig = new ZenModeConfig(); - setDefaultZenRules(mContext); - mConfig = mDefaultConfig; + mDefaultConfig = readDefaultConfig(mContext.getResources()); + updateDefaultAutomaticRuleNames(); + mConfig = mDefaultConfig.copy(); mConfigs.put(UserHandle.USER_SYSTEM, mConfig); mSettingsObserver = new SettingsObserver(mHandler); @@ -311,7 +307,9 @@ public class ZenModeHelper { newConfig = mConfig.copy(); ZenRule rule = new ZenRule(); populateZenRule(automaticZenRule, rule, true); - newConfig.automaticRules.put(rule.id, rule); + if (newConfig.automaticRules.put(rule.id, rule) != null) { + rule.modified = true; + } if (setConfigLocked(newConfig, reason, rule.component, true)) { return rule.id; } else { @@ -341,7 +339,9 @@ public class ZenModeHelper { } } populateZenRule(automaticZenRule, rule, false); - newConfig.automaticRules.put(ruleId, rule); + if (newConfig.automaticRules.put(ruleId, rule) != null) { + rule.modified = true; + } return setConfigLocked(newConfig, reason, rule.component, true); } } @@ -413,17 +413,6 @@ public class ZenModeHelper { } } - public void setDefaultZenRules(Context context) { - mDefaultConfig = readDefaultConfig(context.getResources()); - appendDefaultRules(mDefaultConfig); - } - - private void appendDefaultRules (ZenModeConfig config) { - getDefaultRuleNames(); - appendDefaultEveryNightRule(config); - appendDefaultEventRules(config); - } - // Checks zen rule properties are the same (doesn't check creation time, name nor enabled) // used to check if default rules were customized or not private boolean ruleValuesEqual(AutomaticZenRule rule, ZenRule defaultRule) { @@ -437,22 +426,16 @@ public class ZenModeHelper { } protected void updateDefaultZenRules() { - ZenModeConfig configDefaultRules = new ZenModeConfig(); - appendDefaultRules(configDefaultRules); // "new" localized default rules - for (String ruleId : ZenModeConfig.DEFAULT_RULE_IDS) { - AutomaticZenRule currRule = getAutomaticZenRule(ruleId); - ZenRule defaultRule = configDefaultRules.automaticRules.get(ruleId); - // if default rule wasn't customized, use localized name instead of previous - if (ruleValuesEqual(currRule, defaultRule) && - !defaultRule.name.equals(currRule.getName())) { + updateDefaultAutomaticRuleNames(); + for (ZenRule defaultRule : mDefaultConfig.automaticRules.values()) { + ZenRule currRule = mConfig.automaticRules.get(defaultRule.id); + // if default rule wasn't modified, use localized name instead of previous + if (!currRule.modified && !defaultRule.name.equals(currRule.name)) { if (canManageAutomaticZenRule(defaultRule)) { if (DEBUG) Slog.d(TAG, "Locale change - updating default zen rule name " - + "from " + currRule.getName() + " to " + defaultRule.name); + + "from " + currRule.name + " to " + defaultRule.name); // update default rule (if locale changed, name of rule will change) - AutomaticZenRule defaultAutoRule = createAutomaticZenRule(defaultRule); - // ensure enabled state is carried over from current rule - defaultAutoRule.setEnabled(currRule.isEnabled()); - updateAutomaticZenRule(ruleId, defaultAutoRule, + updateAutomaticZenRule(defaultRule.id, createAutomaticZenRule(defaultRule), "locale changed"); } } @@ -642,7 +625,9 @@ public class ZenModeHelper { // - doesn't already have default rules and // - all previous automatic rules were disabled config.automaticRules = new ArrayMap<>(); - appendDefaultRules(config); + for (ZenRule rule : mDefaultConfig.automaticRules.values()) { + config.automaticRules.put(rule.id, rule); + } reason += ", reset to default rules"; } @@ -854,12 +839,16 @@ public class ZenModeHelper { } } - private void getDefaultRuleNames() { - // on locale-change, these values differ - mDefaultRuleEveryNightName = mContext.getResources() - .getString(R.string.zen_mode_default_every_night_name); - mDefaultRuleEventsName = mContext.getResources() - .getString(R.string.zen_mode_default_events_name); + private void updateDefaultAutomaticRuleNames() { + for (ZenRule rule : mDefaultConfig.automaticRules.values()) { + if (ZenModeConfig.EVENTS_DEFAULT_RULE_ID.equals(rule.id)) { + rule.name = mContext.getResources() + .getString(R.string.zen_mode_default_events_name); + } else if (ZenModeConfig.EVERY_NIGHT_DEFAULT_RULE_ID.equals(rule.id)) { + rule.name = mContext.getResources() + .getString(R.string.zen_mode_default_every_night_name); + } + } } @VisibleForTesting @@ -1001,42 +990,6 @@ public class ZenModeHelper { return new ZenModeConfig(); } - private void appendDefaultEveryNightRule(ZenModeConfig config) { - if (config == null) return; - - final ScheduleInfo weeknights = new ScheduleInfo(); - weeknights.days = ZenModeConfig.ALL_DAYS; - weeknights.startHour = 22; - weeknights.endHour = 7; - weeknights.exitAtAlarm = true; - final ZenRule rule = new ZenRule(); - rule.enabled = false; - rule.name = mDefaultRuleEveryNightName; - rule.conditionId = ZenModeConfig.toScheduleConditionId(weeknights); - rule.zenMode = Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS; - rule.component = ScheduleConditionProvider.COMPONENT; - rule.id = ZenModeConfig.EVERY_NIGHT_DEFAULT_RULE_ID; - rule.creationTime = System.currentTimeMillis(); - config.automaticRules.put(rule.id, rule); - } - - private void appendDefaultEventRules(ZenModeConfig config) { - if (config == null) return; - - final EventInfo events = new EventInfo(); - events.calendar = null; // any calendar - events.reply = EventInfo.REPLY_YES_OR_MAYBE; - final ZenRule rule = new ZenRule(); - rule.enabled = false; - rule.name = mDefaultRuleEventsName; - rule.conditionId = ZenModeConfig.toEventConditionId(events); - rule.zenMode = Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS; - rule.component = EventConditionProvider.COMPONENT; - rule.id = ZenModeConfig.EVENTS_DEFAULT_RULE_ID; - rule.creationTime = System.currentTimeMillis(); - config.automaticRules.put(rule.id, rule); - } - private static int zenSeverity(int zen) { switch (zen) { case Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS: return 1; diff --git a/services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java b/services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java index 91f4bc837eaa..702161e48b75 100644 --- a/services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java @@ -45,6 +45,7 @@ import android.content.ComponentName; import android.content.ContentResolver; import android.content.Context; import android.content.res.Resources; +import android.content.res.XmlResourceParser; import android.media.AudioAttributes; import android.media.AudioManager; import android.media.AudioManagerInternal; @@ -60,6 +61,7 @@ import android.test.suitebuilder.annotation.SmallTest; import android.testing.AndroidTestingRunner; import android.testing.TestableLooper; import android.util.ArrayMap; +import android.util.Log; import android.util.Xml; import com.android.internal.R; @@ -74,12 +76,16 @@ import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.xmlpull.v1.XmlPullParser; +import org.xmlpull.v1.XmlPullParserException; import org.xmlpull.v1.XmlSerializer; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.Reader; @SmallTest @RunWith(AndroidTestingRunner.class) @@ -88,7 +94,7 @@ public class ZenModeHelperTest extends UiServiceTestCase { ConditionProviders mConditionProviders; @Mock NotificationManager mNotificationManager; - @Mock private Resources mResources; + private Resources mResources; private TestableLooper mTestableLooper; private ZenModeHelper mZenModeHelperSpy; private Context mContext; @@ -101,11 +107,17 @@ public class ZenModeHelperTest extends UiServiceTestCase { mTestableLooper = TestableLooper.get(this); mContext = spy(getContext()); mContentResolver = mContext.getContentResolver(); - when(mContext.getResources()).thenReturn(mResources); - when(mResources.getString(R.string.zen_mode_default_every_night_name)).thenReturn("night"); - when(mResources.getString(R.string.zen_mode_default_events_name)).thenReturn("events"); - when(mContext.getSystemService(NotificationManager.class)).thenReturn(mNotificationManager); + mResources = spy(mContext.getResources()); + try { + when(mResources.getXml(R.xml.default_zen_mode_config)).thenReturn( + getDefaultConfigParser()); + } catch (Exception e) { + Log.d("ZenModeHelperTest", "Couldn't mock default zen mode config xml file err=" + + e.toString()); + } + + when(mContext.getSystemService(NotificationManager.class)).thenReturn(mNotificationManager); mConditionProviders = new ConditionProviders(mContext, new UserProfiles(), AppGlobals.getPackageManager()); mConditionProviders.addSystemProvider(new CountdownConditionProvider()); @@ -113,6 +125,30 @@ public class ZenModeHelperTest extends UiServiceTestCase { mConditionProviders)); } + private XmlResourceParser getDefaultConfigParser() throws IOException, XmlPullParserException { + String xml = "<zen version=\"8\" user=\"0\">\n" + + "<allow calls=\"false\" repeatCallers=\"false\" messages=\"true\" " + + "reminders=\"false\" events=\"false\" callsFrom=\"1\" messagesFrom=\"2\" " + + "visualScreenOff=\"true\" alarms=\"true\" " + + "media=\"true\" system=\"false\" />\n" + + "<automatic ruleId=\"EVENTS_DEFAULT_RULE\" enabled=\"false\" snoozing=\"false\"" + + " name=\"Event\" zen=\"1\"" + + " component=\"android/com.android.server.notification.EventConditionProvider\"" + + " conditionId=\"condition://android/event?userId=-10000&calendar=&" + + "reply=1\"/>\n" + + "<automatic ruleId=\"EVERY_NIGHT_DEFAULT_RULE\" enabled=\"false\"" + + " snoozing=\"false\" name=\"Sleeping\" zen=\"1\"" + + " component=\"android/com.android.server.notification.ScheduleConditionProvider\"" + + " conditionId=\"condition://android/schedule?days=1.2.3.4.5.6.7 &start=22.0" + + "&end=7.0&exitAtAlarm=true\"/>" + + "<disallow visualEffects=\"511\" />" + + "</zen>"; + XmlPullParser parser = Xml.newPullParser(); + parser.setInput(new BufferedInputStream(new ByteArrayInputStream(xml.getBytes())), null); + parser.nextTag(); + return new XmlResourceParserImpl(parser); + } + private ByteArrayOutputStream writeXmlAndPurge(boolean forBackup, Integer version) throws Exception { XmlSerializer serializer = new FastXmlSerializer(); @@ -649,8 +685,8 @@ public class ZenModeHelperTest extends UiServiceTestCase { customRule.id = "customRule"; customRule.name = "Custom Rule"; customRule.zenMode = Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS; - customRule.component = new ComponentName("test", "test"); customRule.conditionId = ZenModeConfig.toScheduleConditionId(customRuleInfo); + customRule.component = new ComponentName("android", "ScheduleConditionProvider"); automaticRules.put("customRule", customRule); mZenModeHelperSpy.mConfig.automaticRules = automaticRules; @@ -662,8 +698,8 @@ public class ZenModeHelperTest extends UiServiceTestCase { new ByteArrayInputStream(baos.toByteArray())), null); parser.nextTag(); mZenModeHelperSpy.readXml(parser, true); - assertEquals(original.hashCode(), mZenModeHelperSpy.mConfig.hashCode()); assertEquals(original, mZenModeHelperSpy.mConfig); + assertEquals(original.hashCode(), mZenModeHelperSpy.mConfig.hashCode()); } @Test @@ -678,6 +714,7 @@ public class ZenModeHelperTest extends UiServiceTestCase { customRule.name = "Custom Rule"; customRule.zenMode = Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS; customRule.conditionId = ZenModeConfig.toScheduleConditionId(weeknights); + customRule.component = new ComponentName("android", "ScheduleConditionProvider"); enabledAutoRule.put("customRule", customRule); mZenModeHelperSpy.mConfig.automaticRules = enabledAutoRule; @@ -842,6 +879,7 @@ public class ZenModeHelperTest extends UiServiceTestCase { customRule.name = "Custom Rule"; customRule.zenMode = Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS; customRule.conditionId = ZenModeConfig.toScheduleConditionId(weeknights); + customRule.component = new ComponentName("android", "ScheduleConditionProvider"); disabledAutoRule.put("customRule", customRule); mZenModeHelperSpy.mConfig.automaticRules = disabledAutoRule; @@ -877,6 +915,7 @@ public class ZenModeHelperTest extends UiServiceTestCase { customRule.name = "Custom Rule"; customRule.zenMode = Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS; customRule.conditionId = ZenModeConfig.toScheduleConditionId(customRuleInfo); + customRule.component = new ComponentName("android", "ScheduleConditionProvider"); automaticRules.put("customRule", customRule); ZenModeConfig.ZenRule defaultScheduleRule = new ZenModeConfig.ZenRule(); @@ -886,6 +925,7 @@ public class ZenModeHelperTest extends UiServiceTestCase { defaultScheduleRule.zenMode = Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS; defaultScheduleRule.conditionId = ZenModeConfig.toScheduleConditionId( defaultScheduleRuleInfo); + customRule.component = new ComponentName("android", "ScheduleConditionProvider"); defaultScheduleRule.id = ZenModeConfig.EVERY_NIGHT_DEFAULT_RULE_ID; automaticRules.put(ZenModeConfig.EVERY_NIGHT_DEFAULT_RULE_ID, defaultScheduleRule); @@ -922,6 +962,7 @@ public class ZenModeHelperTest extends UiServiceTestCase { customRule.name = "Custom Rule"; customRule.zenMode = Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS; customRule.conditionId = ZenModeConfig.toScheduleConditionId(customRuleInfo); + customRule.component = new ComponentName("android", "ScheduleConditionProvider"); automaticRules.put("customRule", customRule); ZenModeConfig.ZenRule defaultScheduleRule = new ZenModeConfig.ZenRule(); @@ -1015,4 +1056,294 @@ public class ZenModeHelperTest extends UiServiceTestCase { assertTrue(mZenModeHelperSpy.mConfig.allowRepeatCallers); assertEquals(SUPPRESSED_EFFECT_BADGE, mZenModeHelperSpy.mConfig.suppressedVisualEffects); } + + /** + * Wrapper to use XmlPullParser as XmlResourceParser for Resources.getXml() + */ + final class XmlResourceParserImpl implements XmlResourceParser { + private XmlPullParser parser; + + public XmlResourceParserImpl(XmlPullParser parser) { + this.parser = parser; + } + + public int getEventType() throws XmlPullParserException { + return parser.getEventType(); + } + + @Override + public void setFeature(String name, boolean state) throws XmlPullParserException { + parser.setFeature(name, state); + } + + @Override + public boolean getFeature(String name) { + return false; + } + + @Override + public void setProperty(String name, Object value) throws XmlPullParserException { + parser.setProperty(name, value); + } + + @Override + public Object getProperty(String name) { + return parser.getProperty(name); + } + + @Override + public void setInput(Reader in) throws XmlPullParserException { + parser.setInput(in); + } + + @Override + public void setInput(InputStream inputStream, String inputEncoding) + throws XmlPullParserException { + parser.setInput(inputStream, inputEncoding); + } + + @Override + public String getInputEncoding() { + return parser.getInputEncoding(); + } + + @Override + public void defineEntityReplacementText(String entityName, String replacementText) + throws XmlPullParserException { + parser.defineEntityReplacementText(entityName, replacementText); + } + + @Override + public int getNamespaceCount(int depth) throws XmlPullParserException { + return parser.getNamespaceCount(depth); + } + + @Override + public String getNamespacePrefix(int pos) throws XmlPullParserException { + return parser.getNamespacePrefix(pos); + } + + @Override + public String getNamespaceUri(int pos) throws XmlPullParserException { + return parser.getNamespaceUri(pos); + } + + @Override + public String getNamespace(String prefix) { + return parser.getNamespace(prefix); + } + + @Override + public int getDepth() { + return parser.getDepth(); + } + + @Override + public String getPositionDescription() { + return parser.getPositionDescription(); + } + + @Override + public int getLineNumber() { + return parser.getLineNumber(); + } + + @Override + public int getColumnNumber() { + return parser.getColumnNumber(); + } + + @Override + public boolean isWhitespace() throws XmlPullParserException { + return parser.isWhitespace(); + } + + @Override + public String getText() { + return parser.getText(); + } + + @Override + public char[] getTextCharacters(int[] holderForStartAndLength) { + return parser.getTextCharacters(holderForStartAndLength); + } + + @Override + public String getNamespace() { + return parser.getNamespace(); + } + + @Override + public String getName() { + return parser.getName(); + } + + @Override + public String getPrefix() { + return parser.getPrefix(); + } + + @Override + public boolean isEmptyElementTag() throws XmlPullParserException { + return false; + } + + @Override + public int getAttributeCount() { + return parser.getAttributeCount(); + } + + public int next() throws IOException, XmlPullParserException { + return parser.next(); + } + + @Override + public int nextToken() throws XmlPullParserException, IOException { + return parser.next(); + } + + @Override + public void require(int type, String namespace, String name) + throws XmlPullParserException, IOException { + parser.require(type, namespace, name); + } + + @Override + public String nextText() throws XmlPullParserException, IOException { + return parser.nextText(); + } + + @Override + public String getAttributeNamespace(int index) { + return ""; + } + + @Override + public String getAttributeName(int index) { + return parser.getAttributeName(index); + } + + @Override + public String getAttributePrefix(int index) { + return parser.getAttributePrefix(index); + } + + @Override + public String getAttributeType(int index) { + return parser.getAttributeType(index); + } + + @Override + public boolean isAttributeDefault(int index) { + return parser.isAttributeDefault(index); + } + + @Override + public String getAttributeValue(int index) { + return parser.getAttributeValue(index); + } + + @Override + public String getAttributeValue(String namespace, String name) { + return parser.getAttributeValue(namespace, name); + } + + @Override + public int getAttributeNameResource(int index) { + return 0; + } + + @Override + public int getAttributeListValue(String namespace, String attribute, String[] options, + int defaultValue) { + return 0; + } + + @Override + public boolean getAttributeBooleanValue(String namespace, String attribute, + boolean defaultValue) { + return false; + } + + @Override + public int getAttributeResourceValue(String namespace, String attribute, int defaultValue) { + return 0; + } + + @Override + public int getAttributeIntValue(String namespace, String attribute, int defaultValue) { + return 0; + } + + @Override + public int getAttributeUnsignedIntValue(String namespace, String attribute, + int defaultValue) { + return 0; + } + + @Override + public float getAttributeFloatValue(String namespace, String attribute, + float defaultValue) { + return 0; + } + + @Override + public int getAttributeListValue(int index, String[] options, int defaultValue) { + return 0; + } + + @Override + public boolean getAttributeBooleanValue(int index, boolean defaultValue) { + return false; + } + + @Override + public int getAttributeResourceValue(int index, int defaultValue) { + return 0; + } + + @Override + public int getAttributeIntValue(int index, int defaultValue) { + return 0; + } + + @Override + public int getAttributeUnsignedIntValue(int index, int defaultValue) { + return 0; + } + + @Override + public float getAttributeFloatValue(int index, float defaultValue) { + return 0; + } + + @Override + public String getIdAttribute() { + return null; + } + + @Override + public String getClassAttribute() { + return null; + } + + @Override + public int getIdAttributeResourceValue(int defaultValue) { + return 0; + } + + @Override + public int getStyleAttribute() { + return 0; + } + + @Override + public void close() { + } + + @Override + public int nextTag() throws IOException, XmlPullParserException { + return parser.nextTag(); + } + } } |