Search in sources :

Example 6 with UiThread

use of androidx.annotation.UiThread in project mobile-center-sdk-android by Microsoft.

the class Distribute method notifyInstallProgress.

@UiThread
@VisibleForTesting
synchronized void notifyInstallProgress(boolean isInProgress) {
    mInstallInProgress = isInProgress;
    if (isInProgress) {
        /* Do not attempt to show dialog if application is in the background. */
        if (mForegroundActivity == null) {
            AppCenterLog.warn(LOG_TAG, "Could not display install progress dialog in the background.");
            return;
        }
        if (mReleaseInstallerListener == null) {
            return;
        }
        /* Close to avoid dialog duplicates. */
        mReleaseInstallerListener.hideInstallProgressDialog();
        /* Create and show a new dialog. */
        Dialog progressDialog = mReleaseInstallerListener.showInstallProgressDialog(mForegroundActivity);
        showAndRememberDialogActivity(progressDialog);
    } else {
        if (mReleaseInstallerListener != null) {
            mReleaseInstallerListener.hideInstallProgressDialog();
            mReleaseInstallerListener = null;
        }
    }
}
Also used : AlertDialog(android.app.AlertDialog) Dialog(android.app.Dialog) VisibleForTesting(androidx.annotation.VisibleForTesting) UiThread(androidx.annotation.UiThread)

Example 7 with UiThread

use of androidx.annotation.UiThread in project mapbox-plugins-android by mapbox.

the class LineManager method create.

/**
 * Create a list of lines on the map.
 * <p>
 * Lines are going to be created only for features with a matching geometry.
 * <p>
 * All supported properties are:<br>
 * LineOptions.PROPERTY_LINE_JOIN - String<br>
 * LineOptions.PROPERTY_LINE_OPACITY - Float<br>
 * LineOptions.PROPERTY_LINE_COLOR - String<br>
 * LineOptions.PROPERTY_LINE_WIDTH - Float<br>
 * LineOptions.PROPERTY_LINE_GAP_WIDTH - Float<br>
 * LineOptions.PROPERTY_LINE_OFFSET - Float<br>
 * LineOptions.PROPERTY_LINE_BLUR - Float<br>
 * LineOptions.PROPERTY_LINE_PATTERN - String<br>
 * Learn more about above properties in the <a href="https://www.mapbox.com/mapbox-gl-js/style-spec/">Style specification</a>.
 * <p>
 * Out of spec properties:<br>
 * "is-draggable" - Boolean, true if the line should be draggable, false otherwise
 *
 * @param featureCollection the featureCollection defining the list of lines to build
 * @return the list of built lines
 */
@UiThread
public List<Line> create(@NonNull FeatureCollection featureCollection) {
    List<Feature> features = featureCollection.features();
    List<LineOptions> options = new ArrayList<>();
    if (features != null) {
        for (Feature feature : features) {
            LineOptions option = LineOptions.fromFeature(feature);
            if (option != null) {
                options.add(option);
            }
        }
    }
    return create(options);
}
Also used : ArrayList(java.util.ArrayList) Feature(com.mapbox.geojson.Feature) UiThread(androidx.annotation.UiThread)

Example 8 with UiThread

use of androidx.annotation.UiThread in project Signal-Android by signalapp.

the class ConversationItemThumbnail method setImageResource.

@UiThread
public void setImageResource(@NonNull GlideRequests glideRequests, @NonNull List<Slide> slides, boolean showControls, boolean isPreview) {
    if (slides.size() == 1) {
        Slide slide = slides.get(0);
        if (slide.isVideoGif()) {
            setThumbnailBounds(gifBounds);
        } else {
            setThumbnailBounds(normalBounds);
            if (minimumThumbnailWidth != -1) {
                thumbnail.setMinimumThumbnailWidth(minimumThumbnailWidth);
            }
        }
        thumbnail.setVisibility(VISIBLE);
        album.setVisibility(GONE);
        Attachment attachment = slides.get(0).asAttachment();
        thumbnail.setImageResource(glideRequests, slides.get(0), showControls, isPreview, attachment.getWidth(), attachment.getHeight());
        setTouchDelegate(thumbnail.getTouchDelegate());
    } else {
        thumbnail.setVisibility(GONE);
        album.setVisibility(VISIBLE);
        album.setSlides(glideRequests, slides, showControls);
        setTouchDelegate(album.getTouchDelegate());
    }
}
Also used : Slide(org.thoughtcrime.securesms.mms.Slide) Attachment(org.thoughtcrime.securesms.attachments.Attachment) UiThread(androidx.annotation.UiThread)

Example 9 with UiThread

use of androidx.annotation.UiThread in project Signal-Android by signalapp.

the class ThumbnailView method setImageResource.

@UiThread
public ListenableFuture<Boolean> setImageResource(@NonNull GlideRequests glideRequests, @NonNull Slide slide, boolean showControls, boolean isPreview, int naturalWidth, int naturalHeight) {
    if (showControls) {
        getTransferControls().setSlide(slide);
        getTransferControls().setDownloadClickListener(new DownloadClickDispatcher());
    } else if (transferControls.isPresent()) {
        getTransferControls().setVisibility(View.GONE);
    }
    if (slide.getUri() != null && slide.hasPlayOverlay() && (slide.getTransferState() == AttachmentDatabase.TRANSFER_PROGRESS_DONE || isPreview)) {
        this.playOverlay.setVisibility(View.VISIBLE);
    } else {
        this.playOverlay.setVisibility(View.GONE);
    }
    if (Util.equals(slide, this.slide)) {
        Log.i(TAG, "Not re-loading slide " + slide.asAttachment().getUri());
        return new SettableFuture<>(false);
    }
    if (this.slide != null && this.slide.getFastPreflightId() != null && (!slide.hasVideo() || Util.equals(this.slide.getUri(), slide.getUri())) && Util.equals(this.slide.getFastPreflightId(), slide.getFastPreflightId())) {
        Log.i(TAG, "Not re-loading slide for fast preflight: " + slide.getFastPreflightId());
        this.slide = slide;
        return new SettableFuture<>(false);
    }
    Log.i(TAG, "loading part with id " + slide.asAttachment().getUri() + ", progress " + slide.getTransferState() + ", fast preflight id: " + slide.asAttachment().getFastPreflightId());
    BlurHash previousBlurhash = this.slide != null ? this.slide.getPlaceholderBlur() : null;
    this.slide = slide;
    this.captionIcon.setVisibility(slide.getCaption().isPresent() ? VISIBLE : GONE);
    dimens[WIDTH] = naturalWidth;
    dimens[HEIGHT] = naturalHeight;
    invalidate();
    SettableFuture<Boolean> result = new SettableFuture<>();
    boolean resultHandled = false;
    if (slide.hasPlaceholder() && (previousBlurhash == null || !Objects.equals(slide.getPlaceholderBlur(), previousBlurhash))) {
        buildPlaceholderGlideRequest(glideRequests, slide).into(new GlideBitmapListeningTarget(blurhash, result));
        resultHandled = true;
    } else if (!slide.hasPlaceholder()) {
        glideRequests.clear(blurhash);
        blurhash.setImageDrawable(null);
    }
    if (slide.getUri() != null) {
        if (!MediaUtil.isJpegType(slide.getContentType()) && !MediaUtil.isVideoType(slide.getContentType())) {
            SettableFuture<Boolean> thumbnailFuture = new SettableFuture<>();
            thumbnailFuture.deferTo(result);
            thumbnailFuture.addListener(new BlurhashClearListener(glideRequests, blurhash));
        }
        buildThumbnailGlideRequest(glideRequests, slide).into(new GlideDrawableListeningTarget(image, result));
        resultHandled = true;
    } else {
        glideRequests.clear(image);
        image.setImageDrawable(null);
    }
    if (!resultHandled) {
        result.set(false);
    }
    return result;
}
Also used : SettableFuture(org.thoughtcrime.securesms.util.concurrent.SettableFuture) BlurHash(org.thoughtcrime.securesms.blurhash.BlurHash) UiThread(androidx.annotation.UiThread)

Example 10 with UiThread

use of androidx.annotation.UiThread in project mobile-center-sdk-android by Microsoft.

the class Distribute method resumeDistributeWorkflow.

/**
 * Method that triggers the distribute workflow or proceed to the next step.
 */
@UiThread
private synchronized void resumeDistributeWorkflow() {
    AppCenterLog.debug(LOG_TAG, "Resume distribute workflow...");
    if (mPackageInfo != null && mForegroundActivity != null && !mWorkflowCompleted && isInstanceEnabled()) {
        /* Don't go any further it this is a debug app. */
        if ((mContext.getApplicationInfo().flags & FLAG_DEBUGGABLE) == FLAG_DEBUGGABLE && !mEnabledForDebuggableBuild) {
            AppCenterLog.info(LOG_TAG, "Not checking for in-app updates in debuggable build.");
            mWorkflowCompleted = true;
            mManualCheckForUpdateRequested = false;
            return;
        }
        /* Don't go any further if the app was installed from an app store. */
        if (InstallerUtils.isInstalledFromAppStore(LOG_TAG, mContext)) {
            AppCenterLog.info(LOG_TAG, "Not checking in app updates as installed from a store.");
            mWorkflowCompleted = true;
            mManualCheckForUpdateRequested = false;
            return;
        }
        /* Continue installing a new release if the dialog was shown before resumeDistributeWorkflow. */
        if (mAlertSystemWindowsDialog != null) {
            mAlertSystemWindowsDialog.dismiss();
            mAlertSystemWindowsDialog = null;
            installUpdate();
            return;
        }
        /* Do nothing during installing a new release. */
        if (mInstallInProgress) {
            AppCenterLog.info(LOG_TAG, "Installing in progress...");
            return;
        }
        /*
             * If failed to enable in-app updates on the same app build before, don't go any further.
             * Only if the app build is different (different package hash), try enabling in-app updates again.
             * This applies to private track only.
             */
        boolean isPublicTrack = mUpdateTrack == UpdateTrack.PUBLIC;
        if (!isPublicTrack) {
            String updateSetupFailedPackageHash = SharedPreferencesManager.getString(PREFERENCE_KEY_UPDATE_SETUP_FAILED_PACKAGE_HASH_KEY);
            if (updateSetupFailedPackageHash != null) {
                String releaseHash = DistributeUtils.computeReleaseHash(this.mPackageInfo);
                if (releaseHash.equals(updateSetupFailedPackageHash)) {
                    AppCenterLog.info(LOG_TAG, "Skipping in-app updates setup, because it already failed on this release before.");
                    return;
                } else {
                    AppCenterLog.info(LOG_TAG, "Re-attempting in-app updates setup and cleaning up failure info from storage.");
                    SharedPreferencesManager.remove(PREFERENCE_KEY_UPDATE_SETUP_FAILED_PACKAGE_HASH_KEY);
                    SharedPreferencesManager.remove(PREFERENCE_KEY_UPDATE_SETUP_FAILED_MESSAGE_KEY);
                    SharedPreferencesManager.remove(PREFERENCE_KEY_TESTER_APP_UPDATE_SETUP_FAILED_MESSAGE_KEY);
                }
            }
        }
        /* If we received the redirection parameters before App Center was started/enabled, process them now. */
        if (mBeforeStartRequestId != null) {
            AppCenterLog.debug(LOG_TAG, "Processing redirection parameters we kept in memory before onStarted");
            if (mBeforeStartDistributionGroupId != null) {
                storeRedirectionParameters(mBeforeStartRequestId, mBeforeStartDistributionGroupId, mBeforeStartUpdateToken);
            } else if (mBeforeStartUpdateSetupFailed != null) {
                storeUpdateSetupFailedParameter(mBeforeStartRequestId, mBeforeStartUpdateSetupFailed);
            }
            if (mBeforeStartTesterAppUpdateSetupFailed != null) {
                storeTesterAppUpdateSetupFailedParameter(mBeforeStartRequestId, mBeforeStartTesterAppUpdateSetupFailed);
            }
            mBeforeStartRequestId = null;
            mBeforeStartDistributionGroupId = null;
            mBeforeStartUpdateToken = null;
            mBeforeStartUpdateSetupFailed = null;
            mBeforeStartTesterAppUpdateSetupFailed = null;
            return;
        }
        /* Load cached release details if process restarted and we have such a cache. */
        int downloadState = getStoredDownloadState();
        if (mReleaseDetails == null && downloadState != DOWNLOAD_STATE_COMPLETED) {
            updateReleaseDetails(DistributeUtils.loadCachedReleaseDetails());
            /* If cached release is optional and we have network, we should not reuse it. */
            if (mReleaseDetails != null && !mReleaseDetails.isMandatoryUpdate() && NetworkStateHelper.getSharedInstance(mContext).isNetworkConnected() && downloadState == DOWNLOAD_STATE_AVAILABLE) {
                cancelPreviousTasks();
            }
        }
        /* If process restarted during workflow. */
        if (downloadState != DOWNLOAD_STATE_COMPLETED && downloadState != DOWNLOAD_STATE_AVAILABLE && !mCheckedDownload) {
            /* Discard release if application updated. Then immediately check release. */
            if (mPackageInfo.lastUpdateTime > SharedPreferencesManager.getLong(PREFERENCE_KEY_DOWNLOAD_TIME)) {
                AppCenterLog.debug(LOG_TAG, "Discarding previous download as application updated.");
                cancelPreviousTasks();
            } else /* Otherwise check currently processed release. */
            {
                /*
                     * If app restarted, try to resume (or restart if not available) download.
                     * Install UI will be shown by listener once download will be completed.
                     */
                mCheckedDownload = true;
                resumeDownload();
                /* If downloading mandatory update proceed to restore progress dialog in the meantime. */
                if (mReleaseDetails == null || !mReleaseDetails.isMandatoryUpdate() || downloadState != DOWNLOAD_STATE_ENQUEUED) {
                    return;
                }
            }
        }
        /*
             * If we got a release information but application backgrounded then resumed,
             * check what dialog to restore.
             */
        if (mReleaseDetails != null) {
            /* If we go back to application without installing the mandatory update. */
            if (downloadState == DOWNLOAD_STATE_INSTALLING) {
                /* Show a new modal dialog with only install button. */
                showMandatoryDownloadReadyDialog();
            } else /* If we are still downloading. */
            if (downloadState == DOWNLOAD_STATE_ENQUEUED) {
                /* Resume (or restart if not available) download. */
                resumeDownload();
                /* Refresh mandatory dialog progress or do nothing otherwise. */
                showDownloadProgress();
            } else /* If we were showing unknown sources dialog, restore it. */
            if (mUnknownSourcesDialog != null) {
                /*
                     * Resume click download step if last time we were showing unknown source dialog.
                     * Note that we could be executed here after going to enable settings and being back in app.
                     * We can start download if the setting is now enabled,
                     * otherwise restore dialog if activity rotated or was covered.
                     */
                enqueueDownloadOrShowUnknownSourcesDialog(mReleaseDetails);
            } else /*
                 * Or restore update dialog if that's the last thing we did before being paused.
                 * Also checking we are not about to download (DownloadTask might still be running and thus not enqueued yet).
                 */
            if (mReleaseDownloader == null || !mReleaseDownloader.isDownloading()) {
                showUpdateDialog();
            }
            /*
                 * Normally we would stop processing here after showing/restoring a dialog.
                 * But if we keep restoring a dialog for an update, we should still
                 * check in background if this release is replaced by a more recent one.
                 * Do that extra release check if app restarted AND we are
                 * displaying either an update/unknown sources dialog OR the install dialog.
                 * Basically if we are still downloading an update, we won't check a new one.
                 */
            if (downloadState != DOWNLOAD_STATE_AVAILABLE && downloadState != DOWNLOAD_STATE_INSTALLING) {
                return;
            }
        }
        /*
             * If the in-app updates setup failed, and user ignores the failure, store the error
             * message and also store the package hash that the failure occurred on. The setup
             * will only be re-attempted the next time the app gets updated (and package hash changes).
             */
        String updateSetupFailedMessage = SharedPreferencesManager.getString(PREFERENCE_KEY_UPDATE_SETUP_FAILED_MESSAGE_KEY);
        if (updateSetupFailedMessage != null) {
            AppCenterLog.debug(LOG_TAG, "In-app updates setup failure detected.");
            showUpdateSetupFailedDialog();
            return;
        }
        /* Nothing more to do for now if we are already calling API to check release. */
        if (mCheckReleaseCallId != null) {
            AppCenterLog.verbose(LOG_TAG, "Already checking or checked latest release.");
            return;
        }
        /* Do not proceed if automatic check for update is disabled and manual check for update has not been called. */
        if (mAutomaticCheckForUpdateDisabled && !mManualCheckForUpdateRequested) {
            AppCenterLog.debug(LOG_TAG, "Automatic check for update is disabled. The SDK will not check for update now.");
            return;
        }
        /*
             * Check if we have previously stored the redirection parameters from private group or we simply use public track.
             */
        String updateToken = SharedPreferencesManager.getString(PREFERENCE_KEY_UPDATE_TOKEN);
        String distributionGroupId = SharedPreferencesManager.getString(PREFERENCE_KEY_DISTRIBUTION_GROUP_ID);
        if (isPublicTrack || updateToken != null) {
            /* We have what we need to check for updates via API. */
            decryptAndGetReleaseDetails(isPublicTrack ? null : updateToken, distributionGroupId);
            return;
        }
        /* If not, open native app (if installed) to update setup, unless it already failed. Otherwise, use the browser. */
        String testerAppUpdateSetupFailedMessage = SharedPreferencesManager.getString(PREFERENCE_KEY_TESTER_APP_UPDATE_SETUP_FAILED_MESSAGE_KEY);
        boolean shouldUseTesterAppForUpdateSetup = isAppCenterTesterAppInstalled() && TextUtils.isEmpty(testerAppUpdateSetupFailedMessage) && !mContext.getPackageName().equals(DistributeUtils.TESTER_APP_PACKAGE_NAME);
        if (shouldUseTesterAppForUpdateSetup && !mTesterAppOpenedOrAborted) {
            DistributeUtils.updateSetupUsingTesterApp(mForegroundActivity, mPackageInfo);
            mTesterAppOpenedOrAborted = true;
        } else if (!mBrowserOpenedOrAborted) {
            DistributeUtils.updateSetupUsingBrowser(mForegroundActivity, mInstallUrl, mAppSecret, mPackageInfo);
            mBrowserOpenedOrAborted = true;
        }
    }
}
Also used : SuppressLint(android.annotation.SuppressLint) UiThread(androidx.annotation.UiThread)

Aggregations

UiThread (androidx.annotation.UiThread)22 ArrayList (java.util.ArrayList)5 Feature (com.mapbox.geojson.Feature)4 SuppressLint (android.annotation.SuppressLint)2 PreferenceCategory (androidx.preference.PreferenceCategory)2 Attachment (org.thoughtcrime.securesms.attachments.Attachment)2 BlurHash (org.thoughtcrime.securesms.blurhash.BlurHash)2 Slide (org.thoughtcrime.securesms.mms.Slide)2 SettableFuture (org.thoughtcrime.securesms.util.concurrent.SettableFuture)2 Account (android.accounts.Account)1 AccountManager (android.accounts.AccountManager)1 AlertDialog (android.app.AlertDialog)1 Dialog (android.app.Dialog)1 Notification (android.app.Notification)1 NotificationChannel (android.app.NotificationChannel)1 NotificationManager (android.app.NotificationManager)1 JobInfo (android.app.job.JobInfo)1 JobScheduler (android.app.job.JobScheduler)1 ComponentName (android.content.ComponentName)1 Drawable (android.graphics.drawable.Drawable)1