Merge lp:~karni/ubuntuone-android-files/handling-expired-tokens into lp:ubuntuone-android-files

Proposed by Michał Karnicki
Status: Merged
Merged at revision: 467
Proposed branch: lp:~karni/ubuntuone-android-files/handling-expired-tokens
Merge into: lp:ubuntuone-android-files
Diff against target: 319 lines (+92/-25)
8 files modified
.classpath (+1/-0)
AndroidManifest.xml (+0/-13)
res/layout/fragment_sign_in.xml (+2/-1)
res/values/ids.xml (+1/-0)
res/values/strings.xml (+3/-0)
src/com/ubuntuone/android/files/activity/FilesActivity.java (+26/-9)
src/com/ubuntuone/android/files/fragment/SignInFragment.java (+29/-0)
src/com/ubuntuone/android/files/service/UpDownService.java (+30/-2)
To merge this branch: bzr merge lp:~karni/ubuntuone-android-files/handling-expired-tokens
Reviewer Review Type Date Requested Status
Mike McCracken (community) sanity check Approve
Review via email: mp+195401@code.launchpad.net

Description of the change

I've allowed myself to throw in a couple smaller fixes on the way, please review by commit.

467 - main focus of this branch. Notify the user if an upload fails in background. If the app is in foreground, http 401 is already handled by local broadcast.

TESTED:
Sign in.
Upload a picture.
Remove token from o.u.c/account.
Upload a picture. Notice it fails, "Please reauthenticate" notification shows up.
Press the notification, sign in.
Note in the logs the retry failed alarm re-registered.

468 - (requested by nessita) Make the soft 'ok' button equivalent to pressing 'Sign in' when entering a password.

TESTED:
On sign in form, use the soft 'Ok' button when entering password. The sign in process continues.

469 - Avoid useless roaming notification, when "Only on Wi-Fi" is selected. It's a one liner I didn't test, I am confident it behaves as I expect.

470 - Removed a widget we don't have time to maintain, which used to crash some devices.

TESTED:
Reinstalled the app. Note the widget is no longer visible in the "widgets" screen on my Nexus 4.

To post a comment you must log in.
Revision history for this message
Mike McCracken (mikemc) wrote :

This all looks reasonable. I am not set up to build or test this, so this is just a read-through review.

review: Approve (sanity check)
Revision history for this message
Michał Karnicki (karni) wrote :

Thanks Mike. This will go through QA, I'll make sure of that.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file '.classpath'
2--- .classpath 2012-05-18 15:49:21 +0000
3+++ .classpath 2013-11-15 15:02:42 +0000
4@@ -4,5 +4,6 @@
5 <classpathentry kind="src" path="gen"/>
6 <classpathentry kind="con" path="com.android.ide.eclipse.adt.LIBRARIES"/>
7 <classpathentry kind="con" path="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK"/>
8+ <classpathentry exported="true" kind="con" path="com.android.ide.eclipse.adt.DEPENDENCIES"/>
9 <classpathentry kind="output" path="bin/classes"/>
10 </classpath>
11
12=== modified file 'AndroidManifest.xml'
13--- AndroidManifest.xml 2013-02-22 17:51:47 +0000
14+++ AndroidManifest.xml 2013-11-15 15:02:42 +0000
15@@ -215,19 +215,6 @@
16 </activity>
17 -->
18
19- <activity
20- android:name=".activity.ShortcutsActivity"
21- android:theme="@style/Theme.Transparent"
22- android:exported="false">
23-
24- <intent-filter>
25- <action android:name="android.intent.action.CREATE_SHORTCUT" />
26- <action android:name="com.ubuntuone.android.files.ACTION_START" />
27- <action android:name="com.ubuntuone.android.files.ACTION_UPLOAD_MEDIA_NOW" />
28- <category android:name="android.intent.category.DEFAULT" />
29- </intent-filter>
30- </activity>
31-
32 <service
33 android:name=".authenticator.AuthenticationService"
34 android:exported="true" >
35
36=== modified file 'res/layout/fragment_sign_in.xml'
37--- res/layout/fragment_sign_in.xml 2013-02-22 17:51:47 +0000
38+++ res/layout/fragment_sign_in.xml 2013-11-15 15:02:42 +0000
39@@ -97,7 +97,8 @@
40 android:textColor="@color/text_dark_grey"
41 android:textSize="@dimen/text_size_smaller"
42 u1f:customFont="Ubuntu-B.ttf"
43- android:text="@string/password" />
44+ android:text="@string/password"
45+ android:imeOptions="actionDone" />
46
47 <include
48 android:id="@+id/password_error"
49
50=== modified file 'res/values/ids.xml'
51--- res/values/ids.xml 2012-08-06 20:03:41 +0000
52+++ res/values/ids.xml 2013-11-15 15:02:42 +0000
53@@ -12,6 +12,7 @@
54 <item type="id" name="stat_failed_download_id" />
55 <item type="id" name="stat_roaming_autoupload_off_id" />
56 <item type="id" name="stat_quota_exceeded_id" />
57+ <item type="id" name="stat_please_reauthenticate" />
58
59 <item type="id" name="context_download" />
60 <item type="id" name="context_cancel_download" />
61
62=== modified file 'res/values/strings.xml'
63--- res/values/strings.xml 2013-02-28 16:17:43 +0000
64+++ res/values/strings.xml 2013-11-15 15:02:42 +0000
65@@ -80,6 +80,9 @@
66 <string name="one_account_only">Currently only one Ubuntu One account is supported. If you wish to sign in as a different user, please remove the old account first.</string>
67 <string name="authentication_error">Authentication failed. Probably credentials you have provided are incorrect.</string>
68 <string name="connectivity_error">Connection is down or service is unavailable. Please try again later.</string>
69+
70+ <string name="please_reauthenticate">Please reauthenticate.</string>
71+ <string name="you_have_been_signed_out">You have been signed out.</string>
72
73 <!-- Files activity -->
74 <string name="files_activity_label">Ubuntu One Files</string> <!-- DNT -->
75
76=== modified file 'src/com/ubuntuone/android/files/activity/FilesActivity.java'
77--- src/com/ubuntuone/android/files/activity/FilesActivity.java 2013-02-22 17:51:47 +0000
78+++ src/com/ubuntuone/android/files/activity/FilesActivity.java 2013-11-15 15:02:42 +0000
79@@ -88,6 +88,7 @@
80 import com.ubuntuone.android.files.provider.TransfersContract.Downloads;
81 import com.ubuntuone.android.files.service.MetaService;
82 import com.ubuntuone.android.files.service.MetaService.Status;
83+import com.ubuntuone.android.files.service.AutoUploadService;
84 import com.ubuntuone.android.files.service.MetaServiceHelper;
85 import com.ubuntuone.android.files.service.UpDownService;
86 import com.ubuntuone.android.files.service.UpDownService.OnDownloadListener;
87@@ -163,6 +164,7 @@
88 private Handler mHandler;
89 private DetachableResultReceiver mReceiver;
90 private SignOutBroadcastReceiver mSignOutReceiver;
91+ private boolean mSignOutReceiverRegistered = false;
92
93 private ContentResolver mResolver;
94
95@@ -202,12 +204,6 @@
96 mHandler = new Handler();
97 mReceiver = new DetachableResultReceiver(mHandler);
98
99- mSignOutReceiver = new SignOutBroadcastReceiver();
100- IntentFilter intentFilter =
101- new IntentFilter("com.ubuntuone.android.files.SIGN_OUT");
102- LocalBroadcastManager lbm = LocalBroadcastManager.getInstance(this);
103- lbm.registerReceiver(mSignOutReceiver, intentFilter);
104-
105 mResolver = getContentResolver();
106
107 // Override splash screen background.
108@@ -296,6 +292,8 @@
109 private void suggestAutoUploadConfiguration() {
110 if (!Preferences.isPhotoUploadConfigured()) {
111 startActivity(new Intent(this, AutoUploadSetupActivity.class));
112+ } else if (Preferences.isPhotoUploadEnabled()) {
113+ AutoUploadService.startFrom(this);
114 }
115 }
116
117@@ -374,6 +372,7 @@
118 hideSpinner();
119 }
120 }
121+ registerSignOutReceiver();
122 setCursorAdapterInBackground();
123 }
124
125@@ -415,6 +414,7 @@
126
127 @Override
128 protected void onPause() {
129+ unregisterSignOutReceiver();
130 if (mReceiver != null) {
131 mReceiver.detach();
132 }
133@@ -423,9 +423,6 @@
134
135 @Override
136 public void onDestroy() {
137- LocalBroadcastManager lbm = LocalBroadcastManager.getInstance(this);
138- lbm.unregisterReceiver(mSignOutReceiver);
139-
140 if (mTracker != null) {
141 mTracker.dispatch();
142 mTracker.stop();
143@@ -879,6 +876,7 @@
144 mUploadGrid.show(v);
145 }
146
147+ @SuppressWarnings("unused")
148 private void onActionBarSettingsClicked() {
149 PreferencesActivity.showFrom(this);
150 }
151@@ -1918,6 +1916,25 @@
152 }
153 }
154
155+ private void registerSignOutReceiver() {
156+ if (mSignOutReceiver == null || !mSignOutReceiverRegistered) {
157+ mSignOutReceiver = new SignOutBroadcastReceiver();
158+ IntentFilter intentFilter =
159+ new IntentFilter("com.ubuntuone.android.files.SIGN_OUT");
160+ LocalBroadcastManager lbm = LocalBroadcastManager.getInstance(this);
161+ lbm.registerReceiver(mSignOutReceiver, intentFilter);
162+ mSignOutReceiverRegistered = true;
163+ }
164+ }
165+
166+ private void unregisterSignOutReceiver() {
167+ if (mSignOutReceiver != null && mSignOutReceiverRegistered) {
168+ LocalBroadcastManager lbm = LocalBroadcastManager.getInstance(this);
169+ lbm.unregisterReceiver(mSignOutReceiver);
170+ mSignOutReceiverRegistered = false;
171+ }
172+ }
173+
174 private class SignOutBroadcastReceiver extends BroadcastReceiver {
175 @Override
176 public void onReceive(Context context, Intent intent) {
177
178=== modified file 'src/com/ubuntuone/android/files/fragment/SignInFragment.java'
179--- src/com/ubuntuone/android/files/fragment/SignInFragment.java 2013-02-22 17:51:47 +0000
180+++ src/com/ubuntuone/android/files/fragment/SignInFragment.java 2013-11-15 15:02:42 +0000
181@@ -31,17 +31,23 @@
182 import android.support.v4.app.Fragment;
183 import android.support.v4.app.FragmentManager;
184 import android.support.v4.app.FragmentTransaction;
185+import android.view.KeyEvent;
186 import android.view.LayoutInflater;
187 import android.view.View;
188 import android.view.View.OnClickListener;
189 import android.view.ViewGroup;
190 import android.view.WindowManager;
191+import android.view.inputmethod.EditorInfo;
192+import android.widget.TextView;
193+import android.widget.TextView.OnEditorActionListener;
194
195 import com.google.android.apps.analytics.GoogleAnalyticsTracker;
196+import com.ubuntuone.android.files.Alarms;
197 import com.ubuntuone.android.files.Analytics;
198 import com.ubuntuone.android.files.Constants;
199 import com.ubuntuone.android.files.Preferences;
200 import com.ubuntuone.android.files.R;
201+import com.ubuntuone.android.files.service.AutoUploadService;
202 import com.ubuntuone.android.files.util.AuthenticateUserTask;
203 import com.ubuntuone.android.files.util.AuthenticateUserTask.AuthenticateUserTaskCallback;
204 import com.ubuntuone.android.files.util.Log;
205@@ -120,6 +126,16 @@
206 signInButton = (ButtonPlus) content.findViewById(R.id.sign_in);
207
208 signInButton.setOnClickListener(onButtonClickedListener);
209+ passwordEditText.setOnEditorActionListener(new OnEditorActionListener() {
210+ @Override
211+ public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
212+ if (actionId == EditorInfo.IME_ACTION_DONE) {
213+ onSignInButtonClicked();
214+ return true;
215+ }
216+ return false;
217+ }
218+ });
219 }
220
221 private OnClickListener onButtonClickedListener = new OnClickListener() {
222@@ -252,6 +268,19 @@
223 mTracker.trackEvent("Referee", Analytics.REFERRER, "login", 1);
224
225 final Activity activity = getActivity();
226+ if (activity != null) {
227+ // In case we have reauthenticated:
228+
229+ // Retry failed uploads.
230+ Alarms.maybeRegisterRetryFailedAlarm();
231+
232+ // Restart AutoUploadService.
233+ if (Preferences.isPhotoUploadConfigured() &&
234+ Preferences.isPhotoUploadEnabled()) {
235+ AutoUploadService.startFrom(getActivity());
236+ }
237+ }
238+
239 activity.setResult(Activity.RESULT_OK);
240 activity.finish();
241 }
242
243=== modified file 'src/com/ubuntuone/android/files/service/UpDownService.java'
244--- src/com/ubuntuone/android/files/service/UpDownService.java 2013-02-02 13:25:05 +0000
245+++ src/com/ubuntuone/android/files/service/UpDownService.java 2013-11-15 15:02:42 +0000
246@@ -61,6 +61,7 @@
247 import com.ubuntuone.android.files.R;
248 import com.ubuntuone.android.files.UbuntuOneFiles;
249 import com.ubuntuone.android.files.activity.FilesActivity;
250+import com.ubuntuone.android.files.activity.LoginActivity;
251 import com.ubuntuone.android.files.activity.PreferencesActivity;
252 import com.ubuntuone.android.files.provider.MetaContract.Nodes;
253 import com.ubuntuone.android.files.provider.MetaContract.ResourceState;
254@@ -451,7 +452,10 @@
255 TransferState.QUEUED, TransferState.WAITING);
256
257 if (networkStatusReceiver.isRoaming() && !uploadAlsoWhenRoaming) {
258- notifyRoamingSoAutoUploadDisabled();
259+ // The notification is useless if 'Only on Wi-Fi' is set.
260+ if (!Preferences.getAutoUploadOnlyOnWiFi()) {
261+ notifyRoamingSoAutoUploadDisabled();
262+ }
263 }
264 }
265 }
266@@ -708,7 +712,7 @@
267 TransferState.QUEUED, TransferState.WAITING);
268
269 recentFailedUploadCount++;
270- onFailureCallback(failure);
271+ onFailureCallback(failure);
272 }
273 }
274
275@@ -727,6 +731,7 @@
276 resolver.update(uri, values, null, null);
277
278 recentFailedUploadCount++;
279+
280 onFailureCallback(failure);
281 }
282
283@@ -1118,6 +1123,7 @@
284 // TODO log failure status codes in GA
285 switch (failure.getStatusCode()) {
286 case HttpStatus.SC_UNAUTHORIZED:
287+ showReauthenticateNotification();
288 onUnauthorizedResponse();
289 break;
290 case HttpStatus.SC_PAYMENT_REQUIRED:
291@@ -1200,6 +1206,28 @@
292
293 notificationManager.notify(R.id.stat_failed_upload_id, notification);
294 }
295+
296+ private void showReauthenticateNotification() {
297+ final String title = getString(R.string.please_reauthenticate);
298+ final String text = getString(R.string.you_have_been_signed_out);
299+
300+ final Intent intent = new Intent(
301+ UpDownService.this, LoginActivity.class);
302+ intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
303+ final PendingIntent pi = PendingIntent.getActivity(
304+ getApplicationContext(), 0, intent, 0);
305+
306+ Notification notification = new NotificationCompat.Builder(this)
307+ .setOngoing(false)
308+ .setTicker(title)
309+ .setSmallIcon(R.drawable.stat_u1_logo)
310+ .setOnlyAlertOnce(true)
311+ .setAutoCancel(true)
312+ .build();
313+ notification.setLatestEventInfo(this, title, text, pi);
314+
315+ notificationManager.notify(R.id.stat_please_reauthenticate, notification);
316+ }
317
318 public interface IdleListener {
319 public void isIdle();

Subscribers

People subscribed via source and target branches

to status/vote changes: