Loading java/com/android/contacts/common/widget/SelectPhoneAccountDialogFragment.java +22 −4 Original line number Diff line number Diff line Loading @@ -25,11 +25,13 @@ import android.content.DialogInterface; import android.os.Bundle; import android.os.Handler; import android.os.ResultReceiver; import android.support.annotation.NonNull; import android.support.annotation.Nullable; import android.support.annotation.VisibleForTesting; import android.telecom.PhoneAccount; import android.telecom.PhoneAccountHandle; import android.telecom.TelecomManager; import android.telephony.SubscriptionInfo; import android.text.TextUtils; import android.view.LayoutInflater; import android.view.View; Loading @@ -43,7 +45,10 @@ import android.widget.ListAdapter; import android.widget.TextView; import com.android.contacts.common.R; import com.android.contacts.common.compat.PhoneAccountCompat; import com.android.contacts.common.compat.PhoneNumberUtilsCompat; import com.android.dialer.location.GeoUtil; import com.android.dialer.phonenumberutil.PhoneNumberHelper; import com.android.dialer.telecom.TelecomUtil; import com.google.common.base.Optional; import java.util.ArrayList; import java.util.List; Loading Loading @@ -115,7 +120,9 @@ public class SelectPhoneAccountDialogFragment extends DialogFragment { final Bundle args = new Bundle(); args.putInt(ARG_TITLE_RES_ID, titleResId); args.putBoolean(ARG_CAN_SET_DEFAULT, canSetDefault); if (setDefaultResId != 0) { args.putInt(ARG_SET_DEFAULT_RES_ID, setDefaultResId); } args.putParcelableArrayList(ARG_ACCOUNT_HANDLES, accountHandlesCopy); args.putParcelable(ARG_LISTENER, listener); args.putString(ARG_CALL_ID, callId); Loading Loading @@ -317,8 +324,9 @@ public class SelectPhoneAccountDialogFragment extends DialogFragment { } else { holder.numberTextView.setVisibility(View.VISIBLE); holder.numberTextView.setText( PhoneNumberUtilsCompat.createTtsSpannable( account.getAddress().getSchemeSpecificPart())); PhoneNumberHelper.formatNumberForDisplay( account.getAddress().getSchemeSpecificPart(), getCountryIso(getContext(), accountHandle))); } holder.imageView.setImageDrawable( PhoneAccountCompat.createIconDrawable(account, getContext())); Loading @@ -337,6 +345,16 @@ public class SelectPhoneAccountDialogFragment extends DialogFragment { return rowView; } private static String getCountryIso( Context context, @NonNull PhoneAccountHandle phoneAccountHandle) { Optional<SubscriptionInfo> info = TelecomUtil.getSubscriptionInfo(context, phoneAccountHandle); if (!info.isPresent()) { return GeoUtil.getCurrentCountryIso(context); } return info.get().getCountryIso().toUpperCase(); } private static final class ViewHolder { TextView labelTextView; Loading java/com/android/dialer/app/calllog/CallLogAdapter.java +1 −0 Original line number Diff line number Diff line Loading @@ -960,6 +960,7 @@ public class CallLogAdapter extends GroupingListAdapter } views.callType = cursor.getInt(CallLogQuery.CALL_TYPE); views.voicemailUri = cursor.getString(CallLogQuery.VOICEMAIL_URI); details.voicemailUri = views.voicemailUri; return details; } Loading java/com/android/dialer/app/calllog/PhoneCallDetailsHelper.java +74 −7 Original line number Diff line number Diff line Loading @@ -19,30 +19,39 @@ package com.android.dialer.app.calllog; import android.content.Context; import android.content.res.Resources; import android.graphics.Typeface; import android.net.Uri; import android.provider.CallLog.Calls; import android.provider.ContactsContract.CommonDataKinds.Phone; import android.support.v4.content.ContextCompat; import android.telecom.PhoneAccount; import android.telecom.PhoneAccountHandle; import android.text.TextUtils; import android.text.format.DateUtils; import android.text.util.Linkify; import android.view.Gravity; import android.view.View; import android.widget.TextView; import android.widget.Toast; import com.android.dialer.app.R; import com.android.dialer.app.calllog.calllogcache.CallLogCache; import com.android.dialer.calllogutils.PhoneCallDetails; import com.android.dialer.common.LogUtil; import com.android.dialer.compat.android.provider.VoicemailCompat; import com.android.dialer.logging.ContactSource; import com.android.dialer.oem.MotorolaUtils; import com.android.dialer.phonenumberutil.PhoneNumberHelper; import com.android.dialer.util.DialerUtils; import com.android.voicemail.VoicemailComponent; import com.android.voicemail.impl.transcribe.TranscriptionRatingHelper; import com.google.internal.communications.voicemailtranscription.v1.TranscriptionRatingValue; import java.util.ArrayList; import java.util.Calendar; import java.util.concurrent.TimeUnit; /** Helper class to fill in the views in {@link PhoneCallDetailsViews}. */ public class PhoneCallDetailsHelper { public class PhoneCallDetailsHelper implements TranscriptionRatingHelper.SuccessListener, TranscriptionRatingHelper.FailureListener { /** The maximum number of icons will be shown to represent the call types in a group. */ private static final int MAX_CALL_TYPE_ICONS = 3; Loading Loading @@ -152,13 +161,16 @@ public class PhoneCallDetailsHelper { String transcript = ""; String branding = ""; boolean showRatingPrompt = false; if (!TextUtils.isEmpty(details.transcription)) { transcript = details.transcription; // Set the branding text if the voicemail was transcribed by google // TODO(mdooley): the transcription state is only set by the google transcription code, // but a better solution would be to check the SOURCE_PACKAGE if (details.transcriptionState == VoicemailCompat.TRANSCRIPTION_AVAILABLE) { // Show a transcription quality rating prompt or set the branding text if the voicemail was // transcribed by google if (shouldShowTranscriptionRating(details.transcriptionState, details.accountHandle)) { showRatingPrompt = true; } else if (details.transcriptionState == VoicemailCompat.TRANSCRIPTION_AVAILABLE || details.transcriptionState == VoicemailCompat.TRANSCRIPTION_AVAILABLE_AND_RATED) { branding = mResources.getString(R.string.voicemail_transcription_branding_text); } } else { Loading @@ -183,8 +195,29 @@ public class PhoneCallDetailsHelper { } views.voicemailTranscriptionView.setText(transcript); if (showRatingPrompt) { views.voicemailTranscriptionBrandingView.setVisibility(View.GONE); View ratingView = views.voicemailTranscriptionRatingView; ratingView.setVisibility(View.VISIBLE); ratingView .findViewById(R.id.voicemail_transcription_rating_good) .setOnClickListener( view -> recordTranscriptionRating( TranscriptionRatingValue.GOOD_TRANSCRIPTION, details)); ratingView .findViewById(R.id.voicemail_transcription_rating_bad) .setOnClickListener( view -> recordTranscriptionRating(TranscriptionRatingValue.BAD_TRANSCRIPTION, details)); } else { views.voicemailTranscriptionRatingView.setVisibility(View.GONE); views.voicemailTranscriptionBrandingView.setVisibility(View.VISIBLE); views.voicemailTranscriptionBrandingView.setText(branding); } } // Bold if not read Typeface typeface = details.isRead ? Typeface.SANS_SERIF : Typeface.DEFAULT_BOLD; Loading @@ -198,6 +231,40 @@ public class PhoneCallDetailsHelper { details.isRead ? R.color.call_log_detail_color : R.color.call_log_unread_text_color)); } private boolean shouldShowTranscriptionRating( int transcriptionState, PhoneAccountHandle account) { // TODO(mdooley): add a configurable random element here? return transcriptionState == VoicemailCompat.TRANSCRIPTION_AVAILABLE && VoicemailComponent.get(mContext) .getVoicemailClient() .isVoicemailDonationEnabled(mContext, account); } private void recordTranscriptionRating( TranscriptionRatingValue ratingValue, PhoneCallDetails details) { LogUtil.enterBlock("PhoneCallDetailsHelper.recordTranscriptionRating"); TranscriptionRatingHelper.sendRating( mContext, ratingValue, Uri.parse(details.voicemailUri), this::onRatingSuccess, this::onRatingFailure); } @Override public void onRatingSuccess(Uri voicemailUri) { LogUtil.enterBlock("PhoneCallDetailsHelper.onRatingSuccess"); Toast toast = Toast.makeText(mContext, R.string.voicemail_transcription_rating_thanks, Toast.LENGTH_LONG); toast.setGravity(Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL, 0, 50); toast.show(); } @Override public void onRatingFailure(Throwable t) { LogUtil.e("PhoneCallDetailsHelper.onRatingFailure", "failed to send rating", t); } /** * Builds a string containing the call location and date. For voicemail logs only the call date is * returned because location information is displayed in the call action button Loading java/com/android/dialer/app/calllog/PhoneCallDetailsViews.java +5 −0 Original line number Diff line number Diff line Loading @@ -32,6 +32,7 @@ public final class PhoneCallDetailsViews { public final View transcriptionView; public final TextView voicemailTranscriptionView; public final TextView voicemailTranscriptionBrandingView; public final View voicemailTranscriptionRatingView; public final TextView callAccountLabel; private PhoneCallDetailsViews( Loading @@ -42,6 +43,7 @@ public final class PhoneCallDetailsViews { View transcriptionView, TextView voicemailTranscriptionView, TextView voicemailTranscriptionBrandingView, View voicemailTranscriptionRatingView, TextView callAccountLabel) { this.nameView = nameView; this.callTypeView = callTypeView; Loading @@ -50,6 +52,7 @@ public final class PhoneCallDetailsViews { this.transcriptionView = transcriptionView; this.voicemailTranscriptionView = voicemailTranscriptionView; this.voicemailTranscriptionBrandingView = voicemailTranscriptionBrandingView; this.voicemailTranscriptionRatingView = voicemailTranscriptionRatingView; this.callAccountLabel = callAccountLabel; } Loading @@ -69,6 +72,7 @@ public final class PhoneCallDetailsViews { view.findViewById(R.id.transcription), (TextView) view.findViewById(R.id.voicemail_transcription), (TextView) view.findViewById(R.id.voicemail_transcription_branding), view.findViewById(R.id.voicemail_transcription_rating), (TextView) view.findViewById(R.id.call_account_label)); } Loading @@ -81,6 +85,7 @@ public final class PhoneCallDetailsViews { new View(context), new TextView(context), new TextView(context), new View(context), new TextView(context)); } } java/com/android/dialer/app/res/layout/call_log_list_item.xml +47 −1 Original line number Diff line number Diff line Loading @@ -150,7 +150,7 @@ <LinearLayout android:id="@+id/transcription" android:layout_width="wrap_content" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="@dimen/call_log_icon_margin" android:visibility="gone" Loading @@ -174,8 +174,54 @@ android:textSize="@dimen/call_log_voicemail_transcription_text_size" android:focusable="true" android:nextFocusUp="@id/voicemail_transcription" android:nextFocusDown="@+id/voicemail_transcription_rating" android:paddingTop="2dp"/> <LinearLayout android:id="@+id/voicemail_transcription_rating" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="@dimen/call_log_icon_margin" android:layout_gravity="center_vertical" android:visibility="gone" android:paddingTop="2dp" android:orientation="horizontal"> <TextView style="@style/TranscriptionQualityRating" android:id="@+id/voicemail_transcription_rating_text" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="1" android:gravity="start" android:text="@string/voicemail_transcription_rating"/> <TextView style="@style/TranscriptionQualityRatingLink" android:id="@+id/voicemail_transcription_rating_good" android:layout_width="wrap_content" android:layout_height="wrap_content" android:gravity="end" android:text="@string/voicemail_transcription_rating_good"/> <TextView style="@style/TranscriptionQualityRating" android:id="@+id/voicemail_transcription_rating_separator" android:layout_width="wrap_content" android:layout_height="wrap_content" android:gravity="end" android:text="@string/voicemail_transcription_rating_separator"/> <TextView style="@style/TranscriptionQualityRatingLink" android:id="@+id/voicemail_transcription_rating_bad" android:layout_width="wrap_content" android:layout_height="wrap_content" android:gravity="end" android:text="@string/voicemail_transcription_rating_bad"/> </LinearLayout> </LinearLayout> </LinearLayout> Loading Loading
java/com/android/contacts/common/widget/SelectPhoneAccountDialogFragment.java +22 −4 Original line number Diff line number Diff line Loading @@ -25,11 +25,13 @@ import android.content.DialogInterface; import android.os.Bundle; import android.os.Handler; import android.os.ResultReceiver; import android.support.annotation.NonNull; import android.support.annotation.Nullable; import android.support.annotation.VisibleForTesting; import android.telecom.PhoneAccount; import android.telecom.PhoneAccountHandle; import android.telecom.TelecomManager; import android.telephony.SubscriptionInfo; import android.text.TextUtils; import android.view.LayoutInflater; import android.view.View; Loading @@ -43,7 +45,10 @@ import android.widget.ListAdapter; import android.widget.TextView; import com.android.contacts.common.R; import com.android.contacts.common.compat.PhoneAccountCompat; import com.android.contacts.common.compat.PhoneNumberUtilsCompat; import com.android.dialer.location.GeoUtil; import com.android.dialer.phonenumberutil.PhoneNumberHelper; import com.android.dialer.telecom.TelecomUtil; import com.google.common.base.Optional; import java.util.ArrayList; import java.util.List; Loading Loading @@ -115,7 +120,9 @@ public class SelectPhoneAccountDialogFragment extends DialogFragment { final Bundle args = new Bundle(); args.putInt(ARG_TITLE_RES_ID, titleResId); args.putBoolean(ARG_CAN_SET_DEFAULT, canSetDefault); if (setDefaultResId != 0) { args.putInt(ARG_SET_DEFAULT_RES_ID, setDefaultResId); } args.putParcelableArrayList(ARG_ACCOUNT_HANDLES, accountHandlesCopy); args.putParcelable(ARG_LISTENER, listener); args.putString(ARG_CALL_ID, callId); Loading Loading @@ -317,8 +324,9 @@ public class SelectPhoneAccountDialogFragment extends DialogFragment { } else { holder.numberTextView.setVisibility(View.VISIBLE); holder.numberTextView.setText( PhoneNumberUtilsCompat.createTtsSpannable( account.getAddress().getSchemeSpecificPart())); PhoneNumberHelper.formatNumberForDisplay( account.getAddress().getSchemeSpecificPart(), getCountryIso(getContext(), accountHandle))); } holder.imageView.setImageDrawable( PhoneAccountCompat.createIconDrawable(account, getContext())); Loading @@ -337,6 +345,16 @@ public class SelectPhoneAccountDialogFragment extends DialogFragment { return rowView; } private static String getCountryIso( Context context, @NonNull PhoneAccountHandle phoneAccountHandle) { Optional<SubscriptionInfo> info = TelecomUtil.getSubscriptionInfo(context, phoneAccountHandle); if (!info.isPresent()) { return GeoUtil.getCurrentCountryIso(context); } return info.get().getCountryIso().toUpperCase(); } private static final class ViewHolder { TextView labelTextView; Loading
java/com/android/dialer/app/calllog/CallLogAdapter.java +1 −0 Original line number Diff line number Diff line Loading @@ -960,6 +960,7 @@ public class CallLogAdapter extends GroupingListAdapter } views.callType = cursor.getInt(CallLogQuery.CALL_TYPE); views.voicemailUri = cursor.getString(CallLogQuery.VOICEMAIL_URI); details.voicemailUri = views.voicemailUri; return details; } Loading
java/com/android/dialer/app/calllog/PhoneCallDetailsHelper.java +74 −7 Original line number Diff line number Diff line Loading @@ -19,30 +19,39 @@ package com.android.dialer.app.calllog; import android.content.Context; import android.content.res.Resources; import android.graphics.Typeface; import android.net.Uri; import android.provider.CallLog.Calls; import android.provider.ContactsContract.CommonDataKinds.Phone; import android.support.v4.content.ContextCompat; import android.telecom.PhoneAccount; import android.telecom.PhoneAccountHandle; import android.text.TextUtils; import android.text.format.DateUtils; import android.text.util.Linkify; import android.view.Gravity; import android.view.View; import android.widget.TextView; import android.widget.Toast; import com.android.dialer.app.R; import com.android.dialer.app.calllog.calllogcache.CallLogCache; import com.android.dialer.calllogutils.PhoneCallDetails; import com.android.dialer.common.LogUtil; import com.android.dialer.compat.android.provider.VoicemailCompat; import com.android.dialer.logging.ContactSource; import com.android.dialer.oem.MotorolaUtils; import com.android.dialer.phonenumberutil.PhoneNumberHelper; import com.android.dialer.util.DialerUtils; import com.android.voicemail.VoicemailComponent; import com.android.voicemail.impl.transcribe.TranscriptionRatingHelper; import com.google.internal.communications.voicemailtranscription.v1.TranscriptionRatingValue; import java.util.ArrayList; import java.util.Calendar; import java.util.concurrent.TimeUnit; /** Helper class to fill in the views in {@link PhoneCallDetailsViews}. */ public class PhoneCallDetailsHelper { public class PhoneCallDetailsHelper implements TranscriptionRatingHelper.SuccessListener, TranscriptionRatingHelper.FailureListener { /** The maximum number of icons will be shown to represent the call types in a group. */ private static final int MAX_CALL_TYPE_ICONS = 3; Loading Loading @@ -152,13 +161,16 @@ public class PhoneCallDetailsHelper { String transcript = ""; String branding = ""; boolean showRatingPrompt = false; if (!TextUtils.isEmpty(details.transcription)) { transcript = details.transcription; // Set the branding text if the voicemail was transcribed by google // TODO(mdooley): the transcription state is only set by the google transcription code, // but a better solution would be to check the SOURCE_PACKAGE if (details.transcriptionState == VoicemailCompat.TRANSCRIPTION_AVAILABLE) { // Show a transcription quality rating prompt or set the branding text if the voicemail was // transcribed by google if (shouldShowTranscriptionRating(details.transcriptionState, details.accountHandle)) { showRatingPrompt = true; } else if (details.transcriptionState == VoicemailCompat.TRANSCRIPTION_AVAILABLE || details.transcriptionState == VoicemailCompat.TRANSCRIPTION_AVAILABLE_AND_RATED) { branding = mResources.getString(R.string.voicemail_transcription_branding_text); } } else { Loading @@ -183,8 +195,29 @@ public class PhoneCallDetailsHelper { } views.voicemailTranscriptionView.setText(transcript); if (showRatingPrompt) { views.voicemailTranscriptionBrandingView.setVisibility(View.GONE); View ratingView = views.voicemailTranscriptionRatingView; ratingView.setVisibility(View.VISIBLE); ratingView .findViewById(R.id.voicemail_transcription_rating_good) .setOnClickListener( view -> recordTranscriptionRating( TranscriptionRatingValue.GOOD_TRANSCRIPTION, details)); ratingView .findViewById(R.id.voicemail_transcription_rating_bad) .setOnClickListener( view -> recordTranscriptionRating(TranscriptionRatingValue.BAD_TRANSCRIPTION, details)); } else { views.voicemailTranscriptionRatingView.setVisibility(View.GONE); views.voicemailTranscriptionBrandingView.setVisibility(View.VISIBLE); views.voicemailTranscriptionBrandingView.setText(branding); } } // Bold if not read Typeface typeface = details.isRead ? Typeface.SANS_SERIF : Typeface.DEFAULT_BOLD; Loading @@ -198,6 +231,40 @@ public class PhoneCallDetailsHelper { details.isRead ? R.color.call_log_detail_color : R.color.call_log_unread_text_color)); } private boolean shouldShowTranscriptionRating( int transcriptionState, PhoneAccountHandle account) { // TODO(mdooley): add a configurable random element here? return transcriptionState == VoicemailCompat.TRANSCRIPTION_AVAILABLE && VoicemailComponent.get(mContext) .getVoicemailClient() .isVoicemailDonationEnabled(mContext, account); } private void recordTranscriptionRating( TranscriptionRatingValue ratingValue, PhoneCallDetails details) { LogUtil.enterBlock("PhoneCallDetailsHelper.recordTranscriptionRating"); TranscriptionRatingHelper.sendRating( mContext, ratingValue, Uri.parse(details.voicemailUri), this::onRatingSuccess, this::onRatingFailure); } @Override public void onRatingSuccess(Uri voicemailUri) { LogUtil.enterBlock("PhoneCallDetailsHelper.onRatingSuccess"); Toast toast = Toast.makeText(mContext, R.string.voicemail_transcription_rating_thanks, Toast.LENGTH_LONG); toast.setGravity(Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL, 0, 50); toast.show(); } @Override public void onRatingFailure(Throwable t) { LogUtil.e("PhoneCallDetailsHelper.onRatingFailure", "failed to send rating", t); } /** * Builds a string containing the call location and date. For voicemail logs only the call date is * returned because location information is displayed in the call action button Loading
java/com/android/dialer/app/calllog/PhoneCallDetailsViews.java +5 −0 Original line number Diff line number Diff line Loading @@ -32,6 +32,7 @@ public final class PhoneCallDetailsViews { public final View transcriptionView; public final TextView voicemailTranscriptionView; public final TextView voicemailTranscriptionBrandingView; public final View voicemailTranscriptionRatingView; public final TextView callAccountLabel; private PhoneCallDetailsViews( Loading @@ -42,6 +43,7 @@ public final class PhoneCallDetailsViews { View transcriptionView, TextView voicemailTranscriptionView, TextView voicemailTranscriptionBrandingView, View voicemailTranscriptionRatingView, TextView callAccountLabel) { this.nameView = nameView; this.callTypeView = callTypeView; Loading @@ -50,6 +52,7 @@ public final class PhoneCallDetailsViews { this.transcriptionView = transcriptionView; this.voicemailTranscriptionView = voicemailTranscriptionView; this.voicemailTranscriptionBrandingView = voicemailTranscriptionBrandingView; this.voicemailTranscriptionRatingView = voicemailTranscriptionRatingView; this.callAccountLabel = callAccountLabel; } Loading @@ -69,6 +72,7 @@ public final class PhoneCallDetailsViews { view.findViewById(R.id.transcription), (TextView) view.findViewById(R.id.voicemail_transcription), (TextView) view.findViewById(R.id.voicemail_transcription_branding), view.findViewById(R.id.voicemail_transcription_rating), (TextView) view.findViewById(R.id.call_account_label)); } Loading @@ -81,6 +85,7 @@ public final class PhoneCallDetailsViews { new View(context), new TextView(context), new TextView(context), new View(context), new TextView(context)); } }
java/com/android/dialer/app/res/layout/call_log_list_item.xml +47 −1 Original line number Diff line number Diff line Loading @@ -150,7 +150,7 @@ <LinearLayout android:id="@+id/transcription" android:layout_width="wrap_content" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="@dimen/call_log_icon_margin" android:visibility="gone" Loading @@ -174,8 +174,54 @@ android:textSize="@dimen/call_log_voicemail_transcription_text_size" android:focusable="true" android:nextFocusUp="@id/voicemail_transcription" android:nextFocusDown="@+id/voicemail_transcription_rating" android:paddingTop="2dp"/> <LinearLayout android:id="@+id/voicemail_transcription_rating" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="@dimen/call_log_icon_margin" android:layout_gravity="center_vertical" android:visibility="gone" android:paddingTop="2dp" android:orientation="horizontal"> <TextView style="@style/TranscriptionQualityRating" android:id="@+id/voicemail_transcription_rating_text" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="1" android:gravity="start" android:text="@string/voicemail_transcription_rating"/> <TextView style="@style/TranscriptionQualityRatingLink" android:id="@+id/voicemail_transcription_rating_good" android:layout_width="wrap_content" android:layout_height="wrap_content" android:gravity="end" android:text="@string/voicemail_transcription_rating_good"/> <TextView style="@style/TranscriptionQualityRating" android:id="@+id/voicemail_transcription_rating_separator" android:layout_width="wrap_content" android:layout_height="wrap_content" android:gravity="end" android:text="@string/voicemail_transcription_rating_separator"/> <TextView style="@style/TranscriptionQualityRatingLink" android:id="@+id/voicemail_transcription_rating_bad" android:layout_width="wrap_content" android:layout_height="wrap_content" android:gravity="end" android:text="@string/voicemail_transcription_rating_bad"/> </LinearLayout> </LinearLayout> </LinearLayout> Loading