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;
}
}
}
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);
}
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());
}
}
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;
}
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;
}
}
}
Aggregations