gt:       if (hasSecret) {
context: /**
   * Copyright (C) 2011 Whisper Systems
   *
   * This program is free software: you can redistribute it and/or modify
   * it under the terms of the GNU General Public License as published by
   * the Free Software Foundation, either version 3 of the License, or
   * (at your option) any later version.
   *
   * This program is distributed in the hope that it will be useful,
   * but WITHOUT ANY WARRANTY; without even the implied warranty of
   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   * GNU General Public License for more details.
   *
   * You should have received a copy of the GNU General Public License
   * along with this program.  If not, see <http://www.gnu.org/licenses/>.
   */
  package org.thoughtcrime.securesms.service;
  
  import android.app.Service;
  import android.content.BroadcastReceiver;
  import android.content.ComponentName;
  import android.content.Context;
  import android.content.Intent;
  import android.content.IntentFilter;
  import android.content.ServiceConnection;
  import android.os.Handler;
  import android.os.IBinder;
  import android.os.Message;
  import android.util.Log;
  import android.widget.Toast;
  
  import org.whispersystems.textsecure.crypto.MasterSecret;
  import org.thoughtcrime.securesms.database.CanonicalSessionMigrator;
  import org.thoughtcrime.securesms.util.WorkerThread;
  
  import java.util.Iterator;
  import java.util.LinkedList;
  import java.util.List;
  
  /**
   * Services that handles sending/receiving of SMS/MMS.
   *
   * @author Moxie Marlinspike
   */
  
  public class SendReceiveService extends Service {
  
    public static final String SEND_SMS_ACTION                  = "org.thoughtcrime.securesms.SendReceiveService.SEND_SMS_ACTION";
    public static final String SENT_SMS_ACTION                  = "org.thoughtcrime.securesms.SendReceiveService.SENT_SMS_ACTION";
    public static final String DELIVERED_SMS_ACTION             = "org.thoughtcrime.securesms.SendReceiveService.DELIVERED_SMS_ACTION";
    public static final String RECEIVE_SMS_ACTION               = "org.thoughtcrime.securesms.SendReceiveService.RECEIVE_SMS_ACTION";
    public static final String SEND_MMS_ACTION                  = "org.thoughtcrime.securesms.SendReceiveService.SEND_MMS_ACTION";
    public static final String RECEIVE_MMS_ACTION               = "org.thoughtcrime.securesms.SendReceiveService.RECEIVE_MMS_ACTION";
    public static final String DOWNLOAD_MMS_ACTION              = "org.thoughtcrime.securesms.SendReceiveService.DOWNLOAD_MMS_ACTION";
    public static final String DOWNLOAD_MMS_CONNECTIVITY_ACTION = "org.thoughtcrime.securesms.SendReceiveService.DOWNLOAD_MMS_CONNECTIVITY_ACTION";
    public static final String DOWNLOAD_MMS_PENDING_APN_ACTION  = "org.thoughtcrime.securesms.SendReceiveService.DOWNLOAD_MMS_PENDING_APN_ACTION";
    public static final String RECEIVE_PUSH_ACTION              = "org.thoughtcrime.securesms.SendReceiveService.RECEIVE_PUSH_ACTION";
    public static final String DECRYPTED_PUSH_ACTION            = "org.thoughtcrime.securesms.SendReceiveService.DECRYPTED_PUSH_ACTION";
    public static final String DOWNLOAD_PUSH_ACTION             = "org.thoughtcrime.securesms.SendReceiveService.DOWNLOAD_PUSH_ACTION";
  
    private static final int SEND_SMS              = 0;
    private static final int RECEIVE_SMS           = 1;
    private static final int SEND_MMS              = 2;
    private static final int RECEIVE_MMS           = 3;
    private static final int DOWNLOAD_MMS          = 4;
    private static final int DOWNLOAD_MMS_PENDING  = 5;
    private static final int RECEIVE_PUSH          = 6;
    private static final int DOWNLOAD_PUSH         = 7;
  
    private ToastHandler toastHandler;
  
    private SmsReceiver    smsReceiver;
    private SmsSender      smsSender;
    private MmsReceiver    mmsReceiver;
    private MmsSender      mmsSender;
    private MmsDownloader  mmsDownloader;
    private PushReceiver   pushReceiver;
    private PushDownloader pushDownloader;
  
    private MasterSecret masterSecret;
    private boolean      hasSecret;
  
    private NewKeyReceiver newKeyReceiver;
    private ClearKeyReceiver clearKeyReceiver;
    private List<Runnable> workQueue;
    private List<Runnable> pendingSecretList;
  
    @Override
    public void onCreate() {
      initializeHandlers();
      initializeProcessors();
      initializeAddressCanonicalization();
      initializeWorkQueue();
      initializeMasterSecret();
    }
  
    @Override
    public void onStart(Intent intent, int startId) {
      if (intent == null) return;
  
      String action = intent.getAction();
  
      if (action.equals(SEND_SMS_ACTION))
        scheduleSecretRequiredIntent(SEND_SMS, intent);
      else if (action.equals(RECEIVE_SMS_ACTION))
        scheduleIntent(RECEIVE_SMS, intent);
      else if (action.equals(SENT_SMS_ACTION))
        scheduleIntent(SEND_SMS, intent);
      else if (action.equals(DELIVERED_SMS_ACTION))
        scheduleIntent(SEND_SMS, intent);
      else if (action.equals(SEND_MMS_ACTION))
        scheduleSecretRequiredIntent(SEND_MMS, intent);
      else if (action.equals(RECEIVE_MMS_ACTION))
        scheduleIntent(RECEIVE_MMS, intent);
      else if (action.equals(DOWNLOAD_MMS_ACTION))
        scheduleSecretRequiredIntent(DOWNLOAD_MMS, intent);
      else if (intent.getAction().equals(DOWNLOAD_MMS_PENDING_APN_ACTION))
        scheduleSecretRequiredIntent(DOWNLOAD_MMS_PENDING, intent);
      else if (action.equals(RECEIVE_PUSH_ACTION))
        scheduleIntent(RECEIVE_PUSH, intent);
      else if (action.equals(DECRYPTED_PUSH_ACTION))
        scheduleSecretRequiredIntent(RECEIVE_PUSH, intent);
      else if (action.equals(DOWNLOAD_PUSH_ACTION))
        scheduleSecretRequiredIntent(DOWNLOAD_PUSH, intent);
      else
        Log.w("SendReceiveService", "Received intent with unknown action: " + intent.getAction());
    }
  
    @Override
    public IBinder onBind(Intent intent) {
      return null;
    }
  
    @Override
    public void onDestroy() {
      Log.w("SendReceiveService", "onDestroy()...");
      super.onDestroy();
  
      if (newKeyReceiver != null)
        unregisterReceiver(newKeyReceiver);
  
      if (clearKeyReceiver != null)
        unregisterReceiver(clearKeyReceiver);
    }
  
    private void initializeHandlers() {
      toastHandler = new ToastHandler();
    }
  
    private void initializeProcessors() {
      smsReceiver    = new SmsReceiver(this);
      smsSender      = new SmsSender(this, toastHandler);
      mmsReceiver    = new MmsReceiver(this);
      mmsSender      = new MmsSender(this, toastHandler);
      mmsDownloader  = new MmsDownloader(this, toastHandler);
      pushReceiver   = new PushReceiver(this);
      pushDownloader = new PushDownloader(this);
    }
  
    private void initializeWorkQueue() {
      pendingSecretList = new LinkedList<Runnable>();
      workQueue         = new LinkedList<Runnable>();
  
      Thread workerThread = new WorkerThread(workQueue, "SendReceveService-WorkerThread");
      workerThread.start();
    }
  
    private void initializeMasterSecret() {
      hasSecret           = false;
      newKeyReceiver      = new NewKeyReceiver();
      clearKeyReceiver    = new ClearKeyReceiver();
  
      IntentFilter newKeyFilter = new IntentFilter(KeyCachingService.NEW_KEY_EVENT);
      registerReceiver(newKeyReceiver, newKeyFilter, KeyCachingService.KEY_PERMISSION, null);
  
      IntentFilter clearKeyFilter = new IntentFilter(KeyCachingService.CLEAR_KEY_EVENT);
      registerReceiver(clearKeyReceiver, clearKeyFilter, KeyCachingService.KEY_PERMISSION, null);
  
      Intent bindIntent   = new Intent(this, KeyCachingService.class);
      bindService(bindIntent, serviceConnection, Context.BIND_AUTO_CREATE);
    }
  
    private void initializeWithMasterSecret(MasterSecret masterSecret) {
      Log.w("SendReceiveService", "SendReceive service got master secret.");
  
      if (masterSecret != null) {
        synchronized (workQueue) {
          this.masterSecret = masterSecret;
          this.hasSecret    = true;
  
          Iterator<Runnable> iterator = pendingSecretList.iterator();
          while (iterator.hasNext())
            workQueue.add(iterator.next());
  
          workQueue.notifyAll();
        }
      }
    }
  
    private void initializeAddressCanonicalization() {
      CanonicalSessionMigrator.migrateSessions(this);
    }
  
    private void scheduleIntent(int what, Intent intent) {
      Runnable work = new SendReceiveWorkItem(intent, what);
  
      synchronized (workQueue) {
        workQueue.add(work);
        workQueue.notifyAll();
      }
    }
  
    private void scheduleSecretRequiredIntent(int what, Intent intent) {
      Runnable work = new SendReceiveWorkItem(intent, what);
  
      synchronized (workQueue) {
  