blob: b9c67c68f757efe64ca1c9e09635c5b5961daf62 [file] [log] [blame]
/*
* Copyright (C) 2016 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.documentsui.dirlist;
import android.annotation.Nullable;
import android.app.AuthenticationRequiredException;
import android.app.PendingIntent;
import android.graphics.drawable.Drawable;
import android.util.Log;
import com.android.documentsui.DocumentsApplication;
import com.android.documentsui.Model.Update;
import com.android.documentsui.R;
import com.android.documentsui.base.RootInfo;
import com.android.documentsui.base.Shared;
import com.android.documentsui.dirlist.DocumentsAdapter.Environment;
/**
* Data object used by {@link InflateMessageDocumentHolder} and {@link HeaderMessageDocumentHolder}.
*/
abstract class Message {
protected final Environment mEnv;
// If the message has a button, this will be the default button call back.
protected final Runnable mDefaultCallback;
// If a message has a new callback when updated, this field should be updated.
protected @Nullable Runnable mCallback;
private @Nullable CharSequence mMessageString;
private @Nullable CharSequence mButtonString;
private @Nullable Drawable mIcon;
private boolean mShouldShow = false;
Message(Environment env, Runnable defaultCallback) {
mEnv = env;
mDefaultCallback = defaultCallback;
}
abstract void update(Update Event);
protected void update(CharSequence messageString, CharSequence buttonString, Drawable icon) {
if (messageString == null) {
return;
}
mMessageString = messageString;
mButtonString = buttonString;
mIcon = icon;
mShouldShow = true;
}
void reset() {
mMessageString = null;
mIcon = null;
mShouldShow = false;
}
void runCallback() {
if (mCallback != null) {
mCallback.run();
} else {
mDefaultCallback.run();
}
}
Drawable getIcon() {
return mIcon;
}
boolean shouldShow() {
return mShouldShow;
}
CharSequence getMessageString() {
return mMessageString;
}
CharSequence getButtonString() {
return mButtonString;
}
final static class HeaderMessage extends Message {
private static final String TAG = "HeaderMessage";
HeaderMessage(Environment env, Runnable callback) {
super(env, callback);
}
@Override
void update(Update event) {
reset();
// Error gets first dibs ... for now
// TODO: These should be different Message objects getting updated instead of
// overwriting.
if (event.hasAuthenticationException()) {
updateToAuthenticationExceptionHeader(event);
} else if (mEnv.getModel().error != null) {
update(mEnv.getModel().error, null,
mEnv.getContext().getDrawable(R.drawable.ic_dialog_alert));
} else if (mEnv.getModel().info != null) {
update(mEnv.getModel().info, null,
mEnv.getContext().getDrawable(R.drawable.ic_dialog_info));
}
}
private void updateToAuthenticationExceptionHeader(Update event) {
assert(mEnv.getFeatures().isRemoteActionsEnabled());
RootInfo root = mEnv.getDisplayState().stack.getRoot();
String appName = DocumentsApplication
.getProvidersCache(mEnv.getContext()).getApplicationName(root.authority);
update(mEnv.getContext().getString(R.string.authentication_required, appName),
mEnv.getContext().getResources().getText(R.string.sign_in),
mEnv.getContext().getDrawable(R.drawable.ic_dialog_info));
mCallback = () -> {
AuthenticationRequiredException exception =
(AuthenticationRequiredException) event.getException();
try {
exception.getUserAction().send();
} catch (PendingIntent.CanceledException ignored) {
Log.d(TAG, "User Action either caneled or ignored.");
}
};
}
}
final static class InflateMessage extends Message {
InflateMessage(Environment env, Runnable callback) {
super(env, callback);
}
@Override
void update(Update event) {
reset();
if (event.hasException() && !event.hasAuthenticationException()) {
updateToInflatedErrorMesage(
Shared.DEBUG ? Shared.getStackTrace(event.getException()) : null);
} else if (event.hasAuthenticationException()) {
updateToCantDisplayContentMessage();
} else if (mEnv.getModel().getModelIds().length == 0) {
updateToInflatedEmptyMessage();
}
}
private void updateToInflatedErrorMesage(@Nullable String debugString) {
if (debugString == null) {
update(mEnv.getContext().getResources().getText(R.string.query_error), null,
mEnv.getContext().getDrawable(R.drawable.hourglass));
} else {
assert (Shared.DEBUG);
update(debugString, null, mEnv.getContext().getDrawable(R.drawable.hourglass));
}
}
private void updateToCantDisplayContentMessage() {
update(mEnv.getContext().getResources().getText(R.string.cant_display_content), null,
mEnv.getContext().getDrawable(R.drawable.cabinet));
}
private void updateToInflatedEmptyMessage() {
final CharSequence message;
if (mEnv.isInSearchMode()) {
message = String.format(
String.valueOf(
mEnv.getContext().getResources().getText(R.string.no_results)),
mEnv.getDisplayState().stack.getRoot().title);
} else {
message = mEnv.getContext().getResources().getText(R.string.empty);
}
update(message, null, mEnv.getContext().getDrawable(R.drawable.cabinet));
}
}
}