Skip to content

Commit 87b2298

Browse files
authored
Merge pull request #622 from Microsoft/develop
Version 1.3.0
2 parents fb73430 + eab5d63 commit 87b2298

File tree

17 files changed

+973
-27
lines changed

17 files changed

+973
-27
lines changed

sdk/appcenter-distribute/src/main/java/com/microsoft/appcenter/distribute/BrowserUtils.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,6 @@ static void openBrowser(@NonNull String url, @NonNull Activity activity) {
109109
*
110110
* @param uri initial uri.
111111
* @param appendQuery parameter to append.
112-
*
113112
* @return uri string with appended query item.
114113
*/
115114
static String appendUri(@NonNull String uri, @NonNull String appendQuery) throws URISyntaxException {

sdk/appcenter-distribute/src/main/java/com/microsoft/appcenter/distribute/CheckDownloadTask.java

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,17 @@
99
import android.os.AsyncTask;
1010
import android.os.Build;
1111

12-
import com.microsoft.appcenter.utils.HandlerUtils;
1312
import com.microsoft.appcenter.utils.AppCenterLog;
13+
import com.microsoft.appcenter.utils.HandlerUtils;
14+
import com.microsoft.appcenter.utils.storage.StorageHelper;
1415

1516
import java.util.NoSuchElementException;
1617

1718
import static android.content.Context.DOWNLOAD_SERVICE;
1819
import static com.microsoft.appcenter.distribute.DistributeConstants.INVALID_DOWNLOAD_IDENTIFIER;
1920
import static com.microsoft.appcenter.distribute.DistributeConstants.LOG_TAG;
21+
import static com.microsoft.appcenter.distribute.DistributeConstants.PREFERENCE_KEY_DOWNLOADED_RELEASE_HASH;
22+
import static com.microsoft.appcenter.distribute.DistributeConstants.PREFERENCE_KEY_DOWNLOADED_RELEASE_ID;
2023

2124
/**
2225
* Inspect a pending or completed download.
@@ -154,6 +157,15 @@ protected DownloadProgress doInBackground(Void... params) {
154157
} else {
155158
distribute.completeWorkflow(mReleaseDetails);
156159
}
160+
161+
/* Add downloaded release hash to report after installation. */
162+
if (mReleaseDetails != null) {
163+
AppCenterLog.debug(LOG_TAG, "Store downloaded release hash and id for later reporting.");
164+
StorageHelper.PreferencesStorage.putString(PREFERENCE_KEY_DOWNLOADED_RELEASE_HASH, mReleaseDetails.getReleaseHash());
165+
StorageHelper.PreferencesStorage.putInt(PREFERENCE_KEY_DOWNLOADED_RELEASE_ID, mReleaseDetails.getId());
166+
} else {
167+
AppCenterLog.debug(LOG_TAG, "Release details are missing or broken, will not store release hash and id for reporting.");
168+
}
157169
}
158170
} finally {
159171
cursor.close();

sdk/appcenter-distribute/src/main/java/com/microsoft/appcenter/distribute/DeepLinkActivity.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
import static com.microsoft.appcenter.distribute.DistributeConstants.EXTRA_DISTRIBUTION_GROUP_ID;
1010
import static com.microsoft.appcenter.distribute.DistributeConstants.EXTRA_REQUEST_ID;
11+
import static com.microsoft.appcenter.distribute.DistributeConstants.EXTRA_TESTER_APP_UPDATE_SETUP_FAILED;
1112
import static com.microsoft.appcenter.distribute.DistributeConstants.EXTRA_UPDATE_TOKEN;
1213
import static com.microsoft.appcenter.distribute.DistributeConstants.EXTRA_UPDATE_SETUP_FAILED;
1314
import static com.microsoft.appcenter.distribute.DistributeConstants.LOG_TAG;
@@ -27,11 +28,13 @@ public void onCreate(Bundle savedInstanceState) {
2728
String distributionGroupId = intent.getStringExtra(EXTRA_DISTRIBUTION_GROUP_ID);
2829
String updateToken = intent.getStringExtra(EXTRA_UPDATE_TOKEN);
2930
String updateSetupFailed = intent.getStringExtra(EXTRA_UPDATE_SETUP_FAILED);
31+
String testerAppUpdateSetupFailed = intent.getStringExtra(EXTRA_TESTER_APP_UPDATE_SETUP_FAILED);
3032
AppCenterLog.debug(LOG_TAG, getLocalClassName() + ".getIntent()=" + intent);
3133
AppCenterLog.debug(LOG_TAG, "Intent requestId=" + requestId);
3234
AppCenterLog.debug(LOG_TAG, "Intent distributionGroupId=" + distributionGroupId);
3335
AppCenterLog.debug(LOG_TAG, "Intent updateToken passed=" + (updateToken != null));
3436
AppCenterLog.debug(LOG_TAG, "Intent updateSetupFailed passed=" + (updateSetupFailed != null));
37+
AppCenterLog.debug(LOG_TAG, "Intent testerAppUpdateSetupFailed passed=" + (testerAppUpdateSetupFailed != null));
3538

3639
/* Store redirection parameters if both required values were passed. */
3740
if (requestId != null && distributionGroupId != null) {
@@ -42,6 +45,11 @@ public void onCreate(Bundle savedInstanceState) {
4245
Distribute.getInstance().storeUpdateSetupFailedParameter(requestId, updateSetupFailed);
4346
}
4447

48+
/* If tester app update setup failed, store that info to later retry using the browser update setup */
49+
if (requestId != null && testerAppUpdateSetupFailed != null) {
50+
Distribute.getInstance().storeTesterAppUpdateSetupFailedParameter(requestId, testerAppUpdateSetupFailed);
51+
}
52+
4553
/*
4654
* Resume app exactly where it was before with no activity duplicate, or starting the
4755
* launcher if application task finished or killed (equivalent to clicking from launcher

sdk/appcenter-distribute/src/main/java/com/microsoft/appcenter/distribute/Distribute.java

Lines changed: 105 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,9 @@
3030
import android.widget.Toast;
3131

3232
import com.microsoft.appcenter.AbstractAppCenterService;
33+
import com.microsoft.appcenter.AppCenter;
3334
import com.microsoft.appcenter.channel.Channel;
35+
import com.microsoft.appcenter.distribute.channel.DistributeInfoTracker;
3436
import com.microsoft.appcenter.http.DefaultHttpClient;
3537
import com.microsoft.appcenter.http.HttpClient;
3638
import com.microsoft.appcenter.http.HttpClientNetworkStateHandler;
@@ -77,16 +79,22 @@
7779
import static com.microsoft.appcenter.distribute.DistributeConstants.LOG_TAG;
7880
import static com.microsoft.appcenter.distribute.DistributeConstants.MEBIBYTE_IN_BYTES;
7981
import static com.microsoft.appcenter.distribute.DistributeConstants.NOTIFICATION_CHANNEL_ID;
82+
import static com.microsoft.appcenter.distribute.DistributeConstants.PARAMETER_DISTRIBUTION_GROUP_ID;
83+
import static com.microsoft.appcenter.distribute.DistributeConstants.PARAMETER_INSTALL_ID;
84+
import static com.microsoft.appcenter.distribute.DistributeConstants.PARAMETER_RELEASE_ID;
8085
import static com.microsoft.appcenter.distribute.DistributeConstants.PARAMETER_UPDATE_SETUP_FAILED;
8186
import static com.microsoft.appcenter.distribute.DistributeConstants.POSTPONE_TIME_THRESHOLD;
8287
import static com.microsoft.appcenter.distribute.DistributeConstants.PREFERENCES_NAME_MOBILE_CENTER;
8388
import static com.microsoft.appcenter.distribute.DistributeConstants.PREFERENCE_KEY_DISTRIBUTION_GROUP_ID;
89+
import static com.microsoft.appcenter.distribute.DistributeConstants.PREFERENCE_KEY_DOWNLOADED_RELEASE_HASH;
90+
import static com.microsoft.appcenter.distribute.DistributeConstants.PREFERENCE_KEY_DOWNLOADED_RELEASE_ID;
8491
import static com.microsoft.appcenter.distribute.DistributeConstants.PREFERENCE_KEY_DOWNLOAD_ID;
8592
import static com.microsoft.appcenter.distribute.DistributeConstants.PREFERENCE_KEY_DOWNLOAD_STATE;
8693
import static com.microsoft.appcenter.distribute.DistributeConstants.PREFERENCE_KEY_DOWNLOAD_TIME;
8794
import static com.microsoft.appcenter.distribute.DistributeConstants.PREFERENCE_KEY_POSTPONE_TIME;
8895
import static com.microsoft.appcenter.distribute.DistributeConstants.PREFERENCE_KEY_RELEASE_DETAILS;
8996
import static com.microsoft.appcenter.distribute.DistributeConstants.PREFERENCE_KEY_REQUEST_ID;
97+
import static com.microsoft.appcenter.distribute.DistributeConstants.PREFERENCE_KEY_TESTER_APP_UPDATE_SETUP_FAILED_MESSAGE_KEY;
9098
import static com.microsoft.appcenter.distribute.DistributeConstants.PREFERENCE_KEY_UPDATE_SETUP_FAILED_MESSAGE_KEY;
9199
import static com.microsoft.appcenter.distribute.DistributeConstants.PREFERENCE_KEY_UPDATE_SETUP_FAILED_PACKAGE_HASH_KEY;
92100
import static com.microsoft.appcenter.distribute.DistributeConstants.PREFERENCE_KEY_UPDATE_TOKEN;
@@ -137,6 +145,11 @@ public class Distribute extends AbstractAppCenterService {
137145
*/
138146
private Activity mForegroundActivity;
139147

148+
/**
149+
* Remember if we already tried to open the tester app to update setup.
150+
*/
151+
private boolean mTesterAppOpenedOrAborted;
152+
140153
/**
141154
* Remember if we already tried to open the browser to update setup.
142155
*/
@@ -234,6 +247,11 @@ public class Distribute extends AbstractAppCenterService {
234247
*/
235248
private String mLauncherActivityClassName;
236249

250+
/**
251+
* Channel listener which adds extra fields to logs.
252+
*/
253+
private DistributeInfoTracker mDistributeInfoTracker;
254+
237255
/**
238256
* Custom listener if any.
239257
*/
@@ -424,6 +442,11 @@ public synchronized void onActivityPaused(Activity activity) {
424442
@Override
425443
protected synchronized void applyEnabledState(boolean enabled) {
426444
if (enabled) {
445+
446+
/* Enable the distribute info tracker. */
447+
String distributionGroupId = PreferencesStorage.getString(PREFERENCE_KEY_DISTRIBUTION_GROUP_ID);
448+
mDistributeInfoTracker = new DistributeInfoTracker(distributionGroupId);
449+
mChannel.addListener(mDistributeInfoTracker);
427450
HandlerUtils.runOnUiThread(new Runnable() {
428451

429452
@Override
@@ -434,13 +457,19 @@ public void run() {
434457
} else {
435458

436459
/* Clean all state on disabling, cancel everything. Keep only redirection parameters. */
460+
mTesterAppOpenedOrAborted = false;
437461
mBrowserOpenedOrAborted = false;
438462
mWorkflowCompleted = false;
439463
cancelPreviousTasks();
440464
PreferencesStorage.remove(PREFERENCE_KEY_REQUEST_ID);
441465
PreferencesStorage.remove(PREFERENCE_KEY_POSTPONE_TIME);
442466
PreferencesStorage.remove(PREFERENCE_KEY_UPDATE_SETUP_FAILED_PACKAGE_HASH_KEY);
443467
PreferencesStorage.remove(PREFERENCE_KEY_UPDATE_SETUP_FAILED_MESSAGE_KEY);
468+
PreferencesStorage.remove(PREFERENCE_KEY_TESTER_APP_UPDATE_SETUP_FAILED_MESSAGE_KEY);
469+
470+
/* Disable the distribute info tracker. */
471+
mChannel.removeListener(mDistributeInfoTracker);
472+
mDistributeInfoTracker = null;
444473
}
445474
}
446475

@@ -583,6 +612,7 @@ private synchronized void resumeDistributeWorkflow() {
583612
AppCenterLog.info(LOG_TAG, "Re-attempting in-app updates setup and cleaning up failure info from storage.");
584613
PreferencesStorage.remove(PREFERENCE_KEY_UPDATE_SETUP_FAILED_PACKAGE_HASH_KEY);
585614
PreferencesStorage.remove(PREFERENCE_KEY_UPDATE_SETUP_FAILED_MESSAGE_KEY);
615+
PreferencesStorage.remove(PREFERENCE_KEY_TESTER_APP_UPDATE_SETUP_FAILED_MESSAGE_KEY);
586616
}
587617
}
588618

@@ -728,14 +758,28 @@ else if (mUnknownSourcesDialog != null) {
728758
}
729759
}
730760

731-
/* If not, open browser to update setup. */
732-
if (!mBrowserOpenedOrAborted) {
761+
/* If not, open native app (if installed) to update setup, unless it already failed. Otherwise, use the browser. */
762+
String testerAppUpdateSetupFailedMessage = PreferencesStorage.getString(PREFERENCE_KEY_TESTER_APP_UPDATE_SETUP_FAILED_MESSAGE_KEY);
763+
boolean shouldUseTesterAppForUpdateSetup = isAppCenterTesterAppInstalled() && TextUtils.isEmpty(testerAppUpdateSetupFailedMessage) && !mContext.getPackageName().equals(DistributeUtils.TESTER_APP_PACKAGE_NAME);
764+
if (shouldUseTesterAppForUpdateSetup && !mTesterAppOpenedOrAborted) {
765+
DistributeUtils.updateSetupUsingTesterApp(mForegroundActivity, mPackageInfo);
766+
mTesterAppOpenedOrAborted = true;
767+
} else if (!mBrowserOpenedOrAborted) {
733768
DistributeUtils.updateSetupUsingBrowser(mForegroundActivity, mInstallUrl, mAppSecret, mPackageInfo);
734769
mBrowserOpenedOrAborted = true;
735770
}
736771
}
737772
}
738773

774+
private boolean isAppCenterTesterAppInstalled() {
775+
try {
776+
mContext.getPackageManager().getPackageInfo(DistributeUtils.TESTER_APP_PACKAGE_NAME, 0);
777+
} catch (PackageManager.NameNotFoundException ignored) {
778+
return false;
779+
}
780+
return true;
781+
}
782+
739783
private void decryptAndGetReleaseDetails(String updateToken, String distributionGroupId, boolean mobileCenterFailOver) {
740784

741785
/* Decrypt token if any. */
@@ -759,6 +803,7 @@ private void decryptAndGetReleaseDetails(String updateToken, String distribution
759803
/* If the group was from Mobile Center storage, save it in the new storage. */
760804
if (mobileCenterFailOver) {
761805
PreferencesStorage.putString(PREFERENCE_KEY_DISTRIBUTION_GROUP_ID, distributionGroupId);
806+
mDistributeInfoTracker.updateDistributionGroupId(distributionGroupId);
762807
}
763808

764809
/* Check latest release. */
@@ -816,6 +861,16 @@ synchronized void storeUpdateSetupFailedParameter(@NonNull String requestId, @No
816861
}
817862
}
818863

864+
/**
865+
* Store a flag for failure to enable updates from the tester apps, to later reattempt using the browser update setup.
866+
*/
867+
synchronized void storeTesterAppUpdateSetupFailedParameter(@NonNull String requestId, @NonNull String updateSetupFailed) {
868+
if (requestId.equals(PreferencesStorage.getString(PREFERENCE_KEY_REQUEST_ID))) {
869+
AppCenterLog.debug(LOG_TAG, "Stored tester app update setup failed parameter.");
870+
PreferencesStorage.putString(PREFERENCE_KEY_TESTER_APP_UPDATE_SETUP_FAILED_MESSAGE_KEY, updateSetupFailed);
871+
}
872+
}
873+
819874
/**
820875
* Store update token and possibly trigger application update check.
821876
*/
@@ -837,6 +892,7 @@ synchronized void storeRedirectionParameters(@NonNull String requestId, @NonNull
837892
PreferencesStorage.putString(PREFERENCE_KEY_DISTRIBUTION_GROUP_ID, distributionGroupId);
838893
AppCenterLog.debug(LOG_TAG, "Stored redirection parameters.");
839894
PreferencesStorage.remove(PREFERENCE_KEY_REQUEST_ID);
895+
mDistributeInfoTracker.updateDistributionGroupId(distributionGroupId);
840896
cancelPreviousTasks();
841897
getLatestReleaseDetails(distributionGroupId, updateToken);
842898
} else {
@@ -859,9 +915,9 @@ synchronized void getLatestReleaseDetails(String distributionGroupId, String upd
859915
String releaseHash = computeReleaseHash(mPackageInfo);
860916
String url = mApiUrl;
861917
if (updateToken == null) {
862-
url += String.format(GET_LATEST_PUBLIC_RELEASE_PATH_FORMAT, mAppSecret, distributionGroupId, releaseHash);
918+
url += String.format(GET_LATEST_PUBLIC_RELEASE_PATH_FORMAT, mAppSecret, distributionGroupId, releaseHash, getReportingParametersForUpdatedRelease(true, ""));
863919
} else {
864-
url += String.format(GET_LATEST_PRIVATE_RELEASE_PATH_FORMAT, mAppSecret, releaseHash);
920+
url += String.format(GET_LATEST_PRIVATE_RELEASE_PATH_FORMAT, mAppSecret, releaseHash, getReportingParametersForUpdatedRelease(false, distributionGroupId));
865921
}
866922
Map<String, String> headers = new HashMap<>();
867923
if (updateToken != null) {
@@ -956,6 +1012,7 @@ private synchronized void handleApiCallFailure(Object releaseCallId, Exception e
9561012
AppCenterLog.error(LOG_TAG, "Failed to check latest release:", e);
9571013
PreferencesStorage.remove(PREFERENCE_KEY_DISTRIBUTION_GROUP_ID);
9581014
PreferencesStorage.remove(PREFERENCE_KEY_UPDATE_TOKEN);
1015+
mDistributeInfoTracker.removeDistributionGroupId();
9591016
}
9601017
}
9611018
}
@@ -965,6 +1022,16 @@ private synchronized void handleApiCallFailure(Object releaseCallId, Exception e
9651022
* Handle API call success.
9661023
*/
9671024
private synchronized void handleApiCallSuccess(Object releaseCallId, String rawReleaseDetails, ReleaseDetails releaseDetails) {
1025+
String lastDownloadedReleaseHash = PreferencesStorage.getString(PREFERENCE_KEY_DOWNLOADED_RELEASE_HASH);
1026+
if (!TextUtils.isEmpty(lastDownloadedReleaseHash)) {
1027+
if (lastDownloadedReleaseHash.equals(DistributeUtils.computeReleaseHash(mPackageInfo))) {
1028+
AppCenterLog.debug(LOG_TAG, "Successfully reported app update for downloaded release hash (" + lastDownloadedReleaseHash + "), removing from store..");
1029+
PreferencesStorage.remove(PREFERENCE_KEY_DOWNLOADED_RELEASE_HASH);
1030+
PreferencesStorage.remove(PREFERENCE_KEY_DOWNLOADED_RELEASE_ID);
1031+
} else {
1032+
AppCenterLog.debug(LOG_TAG, "Stored release hash doesn't match current installation, probably downloaded but not installed yet, keep in store");
1033+
}
1034+
}
9681035

9691036
/* Check if state did not change. */
9701037
if (mCheckReleaseCallId == releaseCallId) {
@@ -1009,6 +1076,39 @@ private synchronized void handleApiCallSuccess(Object releaseCallId, String rawR
10091076
}
10101077
}
10111078

1079+
/**
1080+
* Get reporting parameters for updated release.
1081+
*
1082+
* @param isPublic are the parameters for public group or not.
1083+
* For public group we report install_id and release_id.
1084+
* For private group we report distribution_group_id and release_id.
1085+
* @param distributionGroupId distribution group id.
1086+
*/
1087+
@NonNull
1088+
private String getReportingParametersForUpdatedRelease(boolean isPublic, String distributionGroupId) {
1089+
String reportingParameters = "";
1090+
AppCenterLog.debug(LOG_TAG, "Check if we need to report release installation..");
1091+
String lastDownloadedReleaseHash = PreferencesStorage.getString(PREFERENCE_KEY_DOWNLOADED_RELEASE_HASH);
1092+
if (!TextUtils.isEmpty(lastDownloadedReleaseHash)) {
1093+
String currentInstalledReleaseHash = computeReleaseHash(mPackageInfo);
1094+
if (lastDownloadedReleaseHash.equals(currentInstalledReleaseHash)) {
1095+
AppCenterLog.debug(LOG_TAG, "Current release was updated but not reported yet, reporting..");
1096+
if (isPublic) {
1097+
reportingParameters += "&" + PARAMETER_INSTALL_ID + "=" + AppCenter.getInstallId().get();
1098+
} else {
1099+
reportingParameters += "&" + PARAMETER_DISTRIBUTION_GROUP_ID + "=" + distributionGroupId;
1100+
}
1101+
int lastDownloadedReleaseId = PreferencesStorage.getInt(PREFERENCE_KEY_DOWNLOADED_RELEASE_ID);
1102+
reportingParameters += "&" + PARAMETER_RELEASE_ID + "=" + lastDownloadedReleaseId;
1103+
} else {
1104+
AppCenterLog.debug(LOG_TAG, "New release was downloaded but not installed yet, skip reporting.");
1105+
}
1106+
} else {
1107+
AppCenterLog.debug(LOG_TAG, "Current release was already reported, skip reporting.");
1108+
}
1109+
return reportingParameters;
1110+
}
1111+
10121112
/**
10131113
* Check if the fetched release information should be installed.
10141114
*
@@ -1190,6 +1290,7 @@ private synchronized void handleUpdateFailedDialogReinstallAction(DialogInterfac
11901290

11911291
/* Clear the update setup failure info from storage, to re-attempt setup on reinstall. */
11921292
PreferencesStorage.remove(PREFERENCE_KEY_UPDATE_SETUP_FAILED_PACKAGE_HASH_KEY);
1293+
PreferencesStorage.remove(PREFERENCE_KEY_TESTER_APP_UPDATE_SETUP_FAILED_MESSAGE_KEY);
11931294
} else {
11941295
showDisabledToast();
11951296
}

0 commit comments

Comments
 (0)