Use the IMAP IDLE command (see RFC 2177 ), if supported by the server, to enter idle mode so that the server can send unsolicited notifications without the need for the client to constantly poll the server. Use a ConnectionListener to be
()
| 2180 | * @since JavaMail 1.4.1 |
| 2181 | */ |
| 2182 | public void idle() throws MessagingException { |
| 2183 | IMAPProtocol p = null; |
| 2184 | // ASSERT: Must NOT be called with the connection pool |
| 2185 | // synchronization lock held. |
| 2186 | assert !Thread.holdsLock(pool); |
| 2187 | synchronized (this) { |
| 2188 | checkConnected(); |
| 2189 | } |
| 2190 | boolean needNotification = false; |
| 2191 | try { |
| 2192 | synchronized (pool) { |
| 2193 | p = getStoreProtocol("idle"); |
| 2194 | if (pool.idleState != ConnectionPool.RUNNING) { |
| 2195 | // some other thread must be running the IDLE |
| 2196 | // command, we'll just wait for it to finish |
| 2197 | // without aborting it ourselves |
| 2198 | try { |
| 2199 | // give up lock and wait to be not idle |
| 2200 | pool.wait(pool.clientTimeoutInterval); |
| 2201 | if (pool.idleState != ConnectionPool.RUNNING) { |
| 2202 | eu.faircode.email.Log.e("idle timeout"); |
| 2203 | throw new InterruptedException("idle timeout"); |
| 2204 | } |
| 2205 | } catch (InterruptedException ex) { |
| 2206 | // restore the interrupted state, which callers might |
| 2207 | // depend on |
| 2208 | Thread.currentThread().interrupt(); |
| 2209 | // stop waiting and return to caller |
| 2210 | throw new MessagingException("idle interrupted", ex); |
| 2211 | } |
| 2212 | return; |
| 2213 | } |
| 2214 | p.idleStart(); |
| 2215 | needNotification = true; |
| 2216 | pool.idleState = ConnectionPool.IDLE; |
| 2217 | pool.idleProtocol = p; |
| 2218 | } |
| 2219 | |
| 2220 | /* |
| 2221 | * We gave up the pool lock so that other threads |
| 2222 | * can get into the pool far enough to see that we're |
| 2223 | * in IDLE and abort the IDLE. |
| 2224 | * |
| 2225 | * Now we read responses from the IDLE command, especially |
| 2226 | * including unsolicited notifications from the server. |
| 2227 | * We don't hold the pool lock while reading because |
| 2228 | * it protects the idleState and other threads need to be |
| 2229 | * able to examine the state. |
| 2230 | * |
| 2231 | * We hold the pool lock while processing the responses. |
| 2232 | */ |
| 2233 | for (;;) { |
| 2234 | Response r = p.readIdleResponse(); |
| 2235 | synchronized (pool) { |
| 2236 | if (r == null || !p.processIdleResponse(r)) { |
| 2237 | pool.idleState = ConnectionPool.RUNNING; |
| 2238 | pool.idleProtocol = null; |
| 2239 | pool.notifyAll(); |
no test coverage detected