1/*
2 * Copyright (C) 2011 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
17package com.android.exchange;
18
19/**
20 * ActiveSync command error status definitions (EAS 14.0 and later); these are in addition to the
21 * command-specific errors defined for earlier protocol versions
22 */
23public class CommandStatusException extends EasException {
24    private static final long serialVersionUID = 1L;
25
26    // A status response to an EAS account. Responses < 16 correspond to command-specific errors as
27    // reported by EAS versions < 14.0; responses > 100 correspond to generic errors as reported
28    // by EAS versions 14.0 and greater
29    public final int mStatus;
30    // If the error refers to a specific data item, that item's id (as provided by the server) is
31    // stored here
32    public final String mItemId;
33
34    public static class CommandStatus {
35        private static final long serialVersionUID = 1L;
36
37        // Fatal user/provisioning issues (put on security hold)
38        public static final int USER_DISABLED_FOR_SYNC = 126;
39        public static final int USERS_DISABLED_FOR_SYNC = 127;
40        public static final int USER_ON_LEGACY_SERVER_CANT_SYNC = 128;
41        public static final int DEVICE_QUARANTINED = 129;
42        public static final int ACCESS_DENIED = 130;
43        public static final int USER_ACCOUNT_DISABLED = 131;
44        public static final int NOT_PROVISIONABLE_PARTIAL = 139;
45        public static final int NOT_PROVISIONABLE_LEGACY_DEVICE = 141;
46        public static final int TOO_MANY_PARTNERSHIPS = 177;
47
48        // Sync state problems (bad key, multiple client conflict, etc.)
49        public static final int SYNC_STATE_LOCKED = 133;
50        public static final int SYNC_STATE_CORRUPT = 134;
51        public static final int SYNC_STATE_EXISTS = 135;
52        public static final int SYNC_STATE_INVALID = 136;
53
54        // Soft provisioning errors, we need to send Provision command
55        public static final int NEEDS_PROVISIONING_WIPE = 140;
56        public static final int NEEDS_PROVISIONING = 142;
57        public static final int NEEDS_PROVISIONING_REFRESH = 143;
58        public static final int NEEDS_PROVISIONING_INVALID = 144;
59
60        // WTF issues (really shouldn't happen in our implementation)
61        public static final int WTF_INVALID_COMMAND = 137;
62        public static final int WTF_INVALID_PROTOCOL = 138;
63        public static final int WTF_DEVICE_CLAIMS_EXTERNAL_MANAGEMENT = 145;
64        public static final int WTF_UNKNOWN_ITEM_TYPE = 147;
65        public static final int WTF_REQUIRES_PROXY_WITHOUT_SSL = 148;
66
67        // For SmartReply/SmartForward
68        public static final int ITEM_NOT_FOUND = 150;
69
70        // Transient or possibly transient errors
71        public static final int SERVER_ERROR_RETRY = 111;
72        public static final int SYNC_STATE_NOT_FOUND = 132;
73
74        // String version of error status codes (for logging only)
75        private static final int STATUS_TEXT_START = 101;
76        private static final int STATUS_TEXT_END = 150;
77        private static final String[] STATUS_TEXT = {
78            "InvalidContent", "InvalidWBXML", "InvalidXML", "InvalidDateTime", "InvalidIDCombo",
79            "InvalidIDs", "InvalidMIME", "DeviceIdError", "DeviceTypeError", "ServerError",
80            "ServerErrorRetry", "ADAccessDenied", "Quota", "ServerOffline", "SendQuota",
81            "RecipientUnresolved", "ReplyNotAllowed", "SentPreviously", "NoRecipient", "SendFailed",
82            "ReplyFailed", "AttsTooLarge", "NoMailbox", "CantBeAnonymous", "UserNotFound",
83            "UserDisabled", "NewMailbox", "LegacyMailbox", "DeviceBlocked", "AccessDenied",
84            "AcctDisabled", "SyncStateNF", "SyncStateLocked", "SyncStateCorrupt", "SyncStateExists",
85            "SyncStateInvalid", "BadCommand", "BadVersion", "NotFullyProvisionable", "RemoteWipe",
86            "LegacyDevice", "NotProvisioned", "PolicyRefresh", "BadPolicyKey", "ExternallyManaged",
87            "NoRecurrence", "UnexpectedClass", "RemoteHasNoSSL", "InvalidRequest", "ItemNotFound"
88        };
89
90        public static boolean isNeedsProvisioning(int status) {
91            return (status == CommandStatus.NEEDS_PROVISIONING ||
92                    status == CommandStatus.NEEDS_PROVISIONING_REFRESH ||
93                    status == CommandStatus.NEEDS_PROVISIONING_INVALID ||
94                    status == CommandStatus.NEEDS_PROVISIONING_WIPE);
95        }
96
97        public static boolean isBadSyncKey(int status) {
98            return (status == CommandStatus.SYNC_STATE_CORRUPT ||
99                    status == CommandStatus.SYNC_STATE_INVALID);
100        }
101
102        public static boolean isDeniedAccess(int status) {
103            return (status == CommandStatus.USER_DISABLED_FOR_SYNC ||
104                    status == CommandStatus.USERS_DISABLED_FOR_SYNC ||
105                    status == CommandStatus.USER_ON_LEGACY_SERVER_CANT_SYNC ||
106                    status == CommandStatus.DEVICE_QUARANTINED ||
107                    status == CommandStatus.ACCESS_DENIED ||
108                    status == CommandStatus.USER_ACCOUNT_DISABLED ||
109                    status == CommandStatus.NOT_PROVISIONABLE_LEGACY_DEVICE ||
110                    status == CommandStatus.NOT_PROVISIONABLE_PARTIAL ||
111                    status == CommandStatus.TOO_MANY_PARTNERSHIPS);
112        }
113
114        public static boolean isTransientError(int status) {
115            return status == CommandStatus.SYNC_STATE_NOT_FOUND ||
116                status == CommandStatus.SERVER_ERROR_RETRY;
117        }
118
119        public static String toString(int status) {
120            StringBuilder sb = new StringBuilder();
121            sb.append(status);
122            sb.append(" (");
123            if (status < STATUS_TEXT_START || status > STATUS_TEXT_END) {
124                sb.append("unknown");
125            } else {
126                int offset = status - STATUS_TEXT_START;
127                if (offset <= STATUS_TEXT.length) {
128                    sb.append(STATUS_TEXT[offset]);
129                }
130            }
131            sb.append(")");
132            return sb.toString();
133        }
134    }
135
136    public CommandStatusException(int status) {
137        mStatus = status;
138        mItemId = null;
139    }
140
141    public CommandStatusException(int status, String itemId) {
142        mStatus = status;
143        mItemId = itemId;
144    }
145}
146