Messaging: Let there be lambdas
Change-Id: Iee1fc46c92ea9159abb10d92d34baee937bdee0c
This commit is contained in:
@@ -17,7 +17,6 @@
|
|||||||
|
|
||||||
package android.support.v7.mms;
|
package android.support.v7.mms;
|
||||||
|
|
||||||
import android.content.ContentValues;
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.res.Resources;
|
import android.content.res.Resources;
|
||||||
import android.content.res.XmlResourceParser;
|
import android.content.res.XmlResourceParser;
|
||||||
@@ -403,28 +402,25 @@ class DefaultApnSettingsLoader implements ApnSettingsLoader {
|
|||||||
XmlResourceParser xml = null;
|
XmlResourceParser xml = null;
|
||||||
try {
|
try {
|
||||||
xml = mContext.getResources().getXml(R.xml.apns);
|
xml = mContext.getResources().getXml(R.xml.apns);
|
||||||
new ApnsXmlParser(xml, new ApnsXmlParser.ApnProcessor() {
|
new ApnsXmlParser(xml, apnValues -> {
|
||||||
@Override
|
final String mcc = trimWithNullCheck(apnValues.getAsString(APN_MCC));
|
||||||
public void process(ContentValues apnValues) {
|
final String mnc = trimWithNullCheck(apnValues.getAsString(APN_MNC));
|
||||||
final String mcc = trimWithNullCheck(apnValues.getAsString(APN_MCC));
|
final String apn = trimWithNullCheck(apnValues.getAsString(APN_APN));
|
||||||
final String mnc = trimWithNullCheck(apnValues.getAsString(APN_MNC));
|
try {
|
||||||
final String apn = trimWithNullCheck(apnValues.getAsString(APN_APN));
|
if (mccMnc[0] == Integer.parseInt(mcc) &&
|
||||||
try {
|
mccMnc[1] == Integer.parseInt(mnc) &&
|
||||||
if (mccMnc[0] == Integer.parseInt(mcc) &&
|
(TextUtils.isEmpty(apnName) || apnName.equalsIgnoreCase(apn))) {
|
||||||
mccMnc[1] == Integer.parseInt(mnc) &&
|
final String type = apnValues.getAsString(APN_TYPE);
|
||||||
(TextUtils.isEmpty(apnName) || apnName.equalsIgnoreCase(apn))) {
|
final String mmsc = apnValues.getAsString(APN_MMSC);
|
||||||
final String type = apnValues.getAsString(APN_TYPE);
|
final String mmsproxy = apnValues.getAsString(APN_MMSPROXY);
|
||||||
final String mmsc = apnValues.getAsString(APN_MMSC);
|
final String mmsport = apnValues.getAsString(APN_MMSPORT);
|
||||||
final String mmsproxy = apnValues.getAsString(APN_MMSPROXY);
|
final Apn newApn = MemoryApn.from(apns, type, mmsc, mmsproxy, mmsport);
|
||||||
final String mmsport = apnValues.getAsString(APN_MMSPORT);
|
if (newApn != null) {
|
||||||
final Apn newApn = MemoryApn.from(apns, type, mmsc, mmsproxy, mmsport);
|
apns.add(newApn);
|
||||||
if (newApn != null) {
|
|
||||||
apns.add(newApn);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} catch (final NumberFormatException e) {
|
|
||||||
// Ignore
|
|
||||||
}
|
}
|
||||||
|
} catch (final NumberFormatException e) {
|
||||||
|
// Ignore
|
||||||
}
|
}
|
||||||
}).parse();
|
}).parse();
|
||||||
} catch (final Resources.NotFoundException e) {
|
} catch (final Resources.NotFoundException e) {
|
||||||
|
|||||||
@@ -95,21 +95,18 @@ class DefaultCarrierConfigValuesLoader implements CarrierConfigValuesLoader {
|
|||||||
XmlResourceParser xml = null;
|
XmlResourceParser xml = null;
|
||||||
try {
|
try {
|
||||||
xml = subContext.getResources().getXml(R.xml.mms_config);
|
xml = subContext.getResources().getXml(R.xml.mms_config);
|
||||||
new CarrierConfigXmlParser(xml, new CarrierConfigXmlParser.KeyValueProcessor() {
|
new CarrierConfigXmlParser(xml, (type, key, value) -> {
|
||||||
@Override
|
try {
|
||||||
public void process(String type, String key, String value) {
|
if (KEY_TYPE_INT.equals(type)) {
|
||||||
try {
|
values.putInt(key, Integer.parseInt(value));
|
||||||
if (KEY_TYPE_INT.equals(type)) {
|
} else if (KEY_TYPE_BOOL.equals(type)) {
|
||||||
values.putInt(key, Integer.parseInt(value));
|
values.putBoolean(key, Boolean.parseBoolean(value));
|
||||||
} else if (KEY_TYPE_BOOL.equals(type)) {
|
} else if (KEY_TYPE_STRING.equals(type)) {
|
||||||
values.putBoolean(key, Boolean.parseBoolean(value));
|
values.putString(key, value);
|
||||||
} else if (KEY_TYPE_STRING.equals(type)) {
|
|
||||||
values.putString(key, value);
|
|
||||||
}
|
|
||||||
} catch (final NumberFormatException e) {
|
|
||||||
Log.w(MmsService.TAG, "Load carrier value from resources: "
|
|
||||||
+ "invalid " + key + "," + value + "," + type);
|
|
||||||
}
|
}
|
||||||
|
} catch (final NumberFormatException e) {
|
||||||
|
Log.w(MmsService.TAG, "Load carrier value from resources: "
|
||||||
|
+ "invalid " + key + "," + value + "," + type);
|
||||||
}
|
}
|
||||||
}).parse();
|
}).parse();
|
||||||
} catch (final Resources.NotFoundException e) {
|
} catch (final Resources.NotFoundException e) {
|
||||||
|
|||||||
@@ -82,25 +82,23 @@ class DownloadRequest extends MmsRequest {
|
|||||||
if (contentUri == null || pdu == null) {
|
if (contentUri == null || pdu == null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
final Callable<Boolean> copyDownloadedPduToOutput = new Callable<Boolean>() {
|
final Callable<Boolean> copyDownloadedPduToOutput = () -> {
|
||||||
public Boolean call() {
|
ParcelFileDescriptor.AutoCloseOutputStream outStream = null;
|
||||||
ParcelFileDescriptor.AutoCloseOutputStream outStream = null;
|
try {
|
||||||
try {
|
final ContentResolver cr = context.getContentResolver();
|
||||||
final ContentResolver cr = context.getContentResolver();
|
final ParcelFileDescriptor pduFd = cr.openFileDescriptor(contentUri, "w");
|
||||||
final ParcelFileDescriptor pduFd = cr.openFileDescriptor(contentUri, "w");
|
outStream = new ParcelFileDescriptor.AutoCloseOutputStream(pduFd);
|
||||||
outStream = new ParcelFileDescriptor.AutoCloseOutputStream(pduFd);
|
outStream.write(pdu);
|
||||||
outStream.write(pdu);
|
return true;
|
||||||
return true;
|
} catch (IOException e) {
|
||||||
} catch (IOException e) {
|
Log.e(MmsService.TAG, "Writing PDU to downloader: IO exception", e);
|
||||||
Log.e(MmsService.TAG, "Writing PDU to downloader: IO exception", e);
|
return false;
|
||||||
return false;
|
} finally {
|
||||||
} finally {
|
if (outStream != null) {
|
||||||
if (outStream != null) {
|
try {
|
||||||
try {
|
outStream.close();
|
||||||
outStream.close();
|
} catch (IOException ex) {
|
||||||
} catch (IOException ex) {
|
// Ignore
|
||||||
// Ignore
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -251,12 +251,7 @@ public class MmsService extends Service {
|
|||||||
// Handler for scheduling service stop
|
// Handler for scheduling service stop
|
||||||
private final Handler mHandler = new Handler();
|
private final Handler mHandler = new Handler();
|
||||||
// Service stop task
|
// Service stop task
|
||||||
private final Runnable mServiceStopRunnable = new Runnable() {
|
private final Runnable mServiceStopRunnable = this::tryStopService;
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
tryStopService();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Start the service with a request
|
* Start the service with a request
|
||||||
@@ -325,24 +320,21 @@ public class MmsService extends Service {
|
|||||||
final MmsRequest request = intent.getParcelableExtra(EXTRA_REQUEST);
|
final MmsRequest request = intent.getParcelableExtra(EXTRA_REQUEST);
|
||||||
if (request != null) {
|
if (request != null) {
|
||||||
try {
|
try {
|
||||||
retainService(request, new Runnable() {
|
retainService(request, () -> {
|
||||||
@Override
|
try {
|
||||||
public void run() {
|
request.execute(
|
||||||
try {
|
MmsService.this,
|
||||||
request.execute(
|
mNetworkManager,
|
||||||
MmsService.this,
|
getApnSettingsLoader(),
|
||||||
mNetworkManager,
|
getCarrierConfigValuesLoader(),
|
||||||
getApnSettingsLoader(),
|
getUserAgentInfoLoader());
|
||||||
getCarrierConfigValuesLoader(),
|
} catch (Exception e) {
|
||||||
getUserAgentInfoLoader());
|
Log.w(TAG, "Unexpected execution failure", e);
|
||||||
} catch (Exception e) {
|
} finally {
|
||||||
Log.w(TAG, "Unexpected execution failure", e);
|
if (request.getUseWakeLock()) {
|
||||||
} finally {
|
releaseWakeLock();
|
||||||
if (request.getUseWakeLock()) {
|
|
||||||
releaseWakeLock();
|
|
||||||
}
|
|
||||||
releaseService();
|
|
||||||
}
|
}
|
||||||
|
releaseService();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
scheduled = true;
|
scheduled = true;
|
||||||
|
|||||||
@@ -101,38 +101,36 @@ class SendRequest extends MmsRequest {
|
|||||||
if (contentUri == null) {
|
if (contentUri == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
final Callable<byte[]> copyPduToArray = new Callable<byte[]>() {
|
final Callable<byte[]> copyPduToArray = () -> {
|
||||||
public byte[] call() {
|
ParcelFileDescriptor.AutoCloseInputStream inStream = null;
|
||||||
ParcelFileDescriptor.AutoCloseInputStream inStream = null;
|
try {
|
||||||
try {
|
final ContentResolver cr = context.getContentResolver();
|
||||||
final ContentResolver cr = context.getContentResolver();
|
final ParcelFileDescriptor pduFd = cr.openFileDescriptor(contentUri, "r");
|
||||||
final ParcelFileDescriptor pduFd = cr.openFileDescriptor(contentUri, "r");
|
inStream = new ParcelFileDescriptor.AutoCloseInputStream(pduFd);
|
||||||
inStream = new ParcelFileDescriptor.AutoCloseInputStream(pduFd);
|
// Request one extra byte to make sure file not bigger than maxSize
|
||||||
// Request one extra byte to make sure file not bigger than maxSize
|
final byte[] readBuf = new byte[maxSize+1];
|
||||||
final byte[] readBuf = new byte[maxSize+1];
|
final int bytesRead = inStream.read(readBuf, 0, maxSize+1);
|
||||||
final int bytesRead = inStream.read(readBuf, 0, maxSize+1);
|
if (bytesRead <= 0) {
|
||||||
if (bytesRead <= 0) {
|
Log.e(MmsService.TAG, "Reading PDU from sender: empty PDU");
|
||||||
Log.e(MmsService.TAG, "Reading PDU from sender: empty PDU");
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
if (bytesRead > maxSize) {
|
|
||||||
Log.e(MmsService.TAG, "Reading PDU from sender: PDU too large");
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
// Copy and return the exact length of bytes
|
|
||||||
final byte[] result = new byte[bytesRead];
|
|
||||||
System.arraycopy(readBuf, 0, result, 0, bytesRead);
|
|
||||||
return result;
|
|
||||||
} catch (IOException e) {
|
|
||||||
Log.e(MmsService.TAG, "Reading PDU from sender: IO exception", e);
|
|
||||||
return null;
|
return null;
|
||||||
} finally {
|
}
|
||||||
if (inStream != null) {
|
if (bytesRead > maxSize) {
|
||||||
try {
|
Log.e(MmsService.TAG, "Reading PDU from sender: PDU too large");
|
||||||
inStream.close();
|
return null;
|
||||||
} catch (IOException ex) {
|
}
|
||||||
// Ignore
|
// Copy and return the exact length of bytes
|
||||||
}
|
final byte[] result = new byte[bytesRead];
|
||||||
|
System.arraycopy(readBuf, 0, result, 0, bytesRead);
|
||||||
|
return result;
|
||||||
|
} catch (IOException e) {
|
||||||
|
Log.e(MmsService.TAG, "Reading PDU from sender: IO exception", e);
|
||||||
|
return null;
|
||||||
|
} finally {
|
||||||
|
if (inStream != null) {
|
||||||
|
try {
|
||||||
|
inStream.close();
|
||||||
|
} catch (IOException ex) {
|
||||||
|
// Ignore
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -127,14 +127,10 @@ public class BugleApplication extends Application implements UncaughtExceptionHa
|
|||||||
MmsManager.setForceLegacyMms(!bugleGservices.getBoolean(
|
MmsManager.setForceLegacyMms(!bugleGservices.getBoolean(
|
||||||
BugleGservicesKeys.USE_MMS_API_IF_PRESENT,
|
BugleGservicesKeys.USE_MMS_API_IF_PRESENT,
|
||||||
BugleGservicesKeys.USE_MMS_API_IF_PRESENT_DEFAULT));
|
BugleGservicesKeys.USE_MMS_API_IF_PRESENT_DEFAULT));
|
||||||
bugleGservices.registerForChanges(new Runnable() {
|
bugleGservices.registerForChanges(() -> MmsManager.setForceLegacyMms(
|
||||||
@Override
|
!bugleGservices.getBoolean(
|
||||||
public void run() {
|
|
||||||
MmsManager.setForceLegacyMms(!bugleGservices.getBoolean(
|
|
||||||
BugleGservicesKeys.USE_MMS_API_IF_PRESENT,
|
BugleGservicesKeys.USE_MMS_API_IF_PRESENT,
|
||||||
BugleGservicesKeys.USE_MMS_API_IF_PRESENT_DEFAULT));
|
BugleGservicesKeys.USE_MMS_API_IF_PRESENT_DEFAULT)));
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void updateAppConfig(final Context context) {
|
public static void updateAppConfig(final Context context) {
|
||||||
@@ -168,13 +164,7 @@ public class BugleApplication extends Application implements UncaughtExceptionHa
|
|||||||
LogUtil.e(TAG, "Uncaught exception in background thread " + thread, ex);
|
LogUtil.e(TAG, "Uncaught exception in background thread " + thread, ex);
|
||||||
|
|
||||||
final Handler handler = new Handler(getMainLooper());
|
final Handler handler = new Handler(getMainLooper());
|
||||||
handler.post(new Runnable() {
|
handler.post(() -> sSystemUncaughtExceptionHandler.uncaughtException(thread, ex));
|
||||||
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
sSystemUncaughtExceptionHandler.uncaughtException(thread, ex);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} else {
|
} else {
|
||||||
sSystemUncaughtExceptionHandler.uncaughtException(thread, ex);
|
sSystemUncaughtExceptionHandler.uncaughtException(thread, ex);
|
||||||
}
|
}
|
||||||
@@ -192,17 +182,13 @@ public class BugleApplication extends Application implements UncaughtExceptionHa
|
|||||||
final File file = DebugUtils.getDebugFile("startup.trace", true);
|
final File file = DebugUtils.getDebugFile("startup.trace", true);
|
||||||
if (file != null) {
|
if (file != null) {
|
||||||
android.os.Debug.startMethodTracing(file.getAbsolutePath(), 160 * 1024 * 1024);
|
android.os.Debug.startMethodTracing(file.getAbsolutePath(), 160 * 1024 * 1024);
|
||||||
new Handler(Looper.getMainLooper()).postDelayed(
|
new Handler(Looper.getMainLooper()).postDelayed(() -> {
|
||||||
new Runnable() {
|
android.os.Debug.stopMethodTracing();
|
||||||
@Override
|
// Allow world to see trace file
|
||||||
public void run() {
|
DebugUtils.ensureReadable(file);
|
||||||
android.os.Debug.stopMethodTracing();
|
LogUtil.d(LogUtil.PROFILE_TAG, "Tracing complete - "
|
||||||
// Allow world to see trace file
|
+ file.getAbsolutePath());
|
||||||
DebugUtils.ensureReadable(file);
|
}, 30000);
|
||||||
LogUtil.d(LogUtil.PROFILE_TAG, "Tracing complete - "
|
|
||||||
+ file.getAbsolutePath());
|
|
||||||
}
|
|
||||||
}, 30000);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -219,13 +205,8 @@ public class BugleApplication extends Application implements UncaughtExceptionHa
|
|||||||
// Perform upgrade on application-wide prefs.
|
// Perform upgrade on application-wide prefs.
|
||||||
factory.getApplicationPrefs().onUpgrade(existingVersion, targetVersion);
|
factory.getApplicationPrefs().onUpgrade(existingVersion, targetVersion);
|
||||||
// Perform upgrade on each subscription's prefs.
|
// Perform upgrade on each subscription's prefs.
|
||||||
PhoneUtils.forEachActiveSubscription(new PhoneUtils.SubscriptionRunnable() {
|
PhoneUtils.forEachActiveSubscription(subId -> factory.getSubscriptionPrefs(subId)
|
||||||
@Override
|
.onUpgrade(existingVersion, targetVersion));
|
||||||
public void runForSubscription(final int subId) {
|
|
||||||
factory.getSubscriptionPrefs(subId)
|
|
||||||
.onUpgrade(existingVersion, targetVersion);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
factory.getApplicationPrefs().putInt(BuglePrefsKeys.SHARED_PREFERENCES_VERSION,
|
factory.getApplicationPrefs().putInt(BuglePrefsKeys.SHARED_PREFERENCES_VERSION,
|
||||||
targetVersion);
|
targetVersion);
|
||||||
} catch (final Exception ex) {
|
} catch (final Exception ex) {
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2015 The Android Open Source Project
|
* Copyright (C) 2015 The Android Open Source Project
|
||||||
|
* Copyright (C) 2024 The LineageOS Project
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -117,13 +118,10 @@ class FactoryImpl extends Factory {
|
|||||||
|
|
||||||
mApplication.initializeSync(this);
|
mApplication.initializeSync(this);
|
||||||
|
|
||||||
final Thread asyncInitialization = new Thread() {
|
final Thread asyncInitialization = new Thread(() -> {
|
||||||
@Override
|
Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
|
||||||
public void run() {
|
mApplication.initializeAsync(FactoryImpl.this);
|
||||||
Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
|
});
|
||||||
mApplication.initializeAsync(FactoryImpl.this);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
asyncInitialization.start();
|
asyncInitialization.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2015 The Android Open Source Project
|
* Copyright (C) 2015 The Android Open Source Project
|
||||||
|
* Copyright (C) 2024 The LineageOS Project
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -1085,12 +1086,7 @@ public class BugleNotifications {
|
|||||||
OBSERVABLE_CONVERSATION_NOTIFICATION_VOLUME);
|
OBSERVABLE_CONVERSATION_NOTIFICATION_VOLUME);
|
||||||
|
|
||||||
// Stop the sound after five seconds to handle continuous ringtones
|
// Stop the sound after five seconds to handle continuous ringtones
|
||||||
ThreadUtil.getMainThreadHandler().postDelayed(new Runnable() {
|
ThreadUtil.getMainThreadHandler().postDelayed(player::stop, 5000);
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
player.stop();
|
|
||||||
}
|
|
||||||
}, 5000);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean isWearCompanionAppInstalled() {
|
public static boolean isWearCompanionAppInstalled() {
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2015 The Android Open Source Project
|
* Copyright (C) 2015 The Android Open Source Project
|
||||||
|
* Copyright (C) 2024 The LineageOS Project
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -235,17 +236,14 @@ public class DataModelImpl extends DataModel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void createConnectivityUtilForEachActiveSubscription() {
|
private void createConnectivityUtilForEachActiveSubscription() {
|
||||||
PhoneUtils.forEachActiveSubscription(new PhoneUtils.SubscriptionRunnable() {
|
PhoneUtils.forEachActiveSubscription(subId -> {
|
||||||
@Override
|
// Create the ConnectivityUtil instance for given subId if absent.
|
||||||
public void runForSubscription(int subId) {
|
if (subId <= ParticipantData.DEFAULT_SELF_SUB_ID) {
|
||||||
// Create the ConnectivityUtil instance for given subId if absent.
|
subId = PhoneUtils.getDefault().getDefaultSmsSubscriptionId();
|
||||||
if (subId <= ParticipantData.DEFAULT_SELF_SUB_ID) {
|
}
|
||||||
subId = PhoneUtils.getDefault().getDefaultSmsSubscriptionId();
|
if (!sConnectivityUtilInstanceCacheN.containsKey(subId)) {
|
||||||
}
|
sConnectivityUtilInstanceCacheN.put(
|
||||||
if (!sConnectivityUtilInstanceCacheN.containsKey(subId)) {
|
subId, new ConnectivityUtil(mContext, subId));
|
||||||
sConnectivityUtilInstanceCacheN.put(
|
|
||||||
subId, new ConnectivityUtil(mContext, subId));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -67,12 +67,7 @@ public class DatabaseWrapper {
|
|||||||
|
|
||||||
// track transaction on a per thread basis
|
// track transaction on a per thread basis
|
||||||
private static final ThreadLocal<Stack<TransactionData>> sTransactionDepth =
|
private static final ThreadLocal<Stack<TransactionData>> sTransactionDepth =
|
||||||
new ThreadLocal<Stack<TransactionData>>() {
|
ThreadLocal.withInitial(() -> new Stack<TransactionData>());
|
||||||
@Override
|
|
||||||
public Stack<TransactionData> initialValue() {
|
|
||||||
return new Stack<TransactionData>();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
private static final String[] sFormatStrings = new String[] {
|
private static final String[] sFormatStrings = new String[] {
|
||||||
"took %d ms to %s",
|
"took %d ms to %s",
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2015 The Android Open Source Project
|
* Copyright (C) 2015 The Android Open Source Project
|
||||||
|
* Copyright (C) 2024 The LineageOS Project
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -25,7 +26,6 @@ import com.android.messaging.util.ContactUtil;
|
|||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Comparator;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A cursor builder that takes the frequent contacts cursor and aggregate it with the all contacts
|
* A cursor builder that takes the frequent contacts cursor and aggregate it with the all contacts
|
||||||
@@ -155,37 +155,34 @@ public class FrequentContactsCursorBuilder {
|
|||||||
|
|
||||||
// Now we have a list of rows containing frequent contacts in alphabetical order.
|
// Now we have a list of rows containing frequent contacts in alphabetical order.
|
||||||
// Therefore, sort all the rows according to their actual ranks in the frequents list.
|
// Therefore, sort all the rows according to their actual ranks in the frequents list.
|
||||||
Collections.sort(rows, new Comparator<Object[]>() {
|
Collections.sort(rows, (lhs, rhs) -> {
|
||||||
@Override
|
final String lookupKeyLhs = (String) lhs[ContactUtil.INDEX_LOOKUP_KEY];
|
||||||
public int compare(final Object[] lhs, final Object[] rhs) {
|
final String lookupKeyRhs = (String) rhs[ContactUtil.INDEX_LOOKUP_KEY];
|
||||||
final String lookupKeyLhs = (String) lhs[ContactUtil.INDEX_LOOKUP_KEY];
|
Assert.isTrue(lookupKeyToRankMap.containsKey(lookupKeyLhs) &&
|
||||||
final String lookupKeyRhs = (String) rhs[ContactUtil.INDEX_LOOKUP_KEY];
|
lookupKeyToRankMap.containsKey(lookupKeyRhs));
|
||||||
Assert.isTrue(lookupKeyToRankMap.containsKey(lookupKeyLhs) &&
|
final int rankLhs = lookupKeyToRankMap.get(lookupKeyLhs);
|
||||||
lookupKeyToRankMap.containsKey(lookupKeyRhs));
|
final int rankRhs = lookupKeyToRankMap.get(lookupKeyRhs);
|
||||||
final int rankLhs = lookupKeyToRankMap.get(lookupKeyLhs);
|
if (rankLhs < rankRhs) {
|
||||||
final int rankRhs = lookupKeyToRankMap.get(lookupKeyRhs);
|
return -1;
|
||||||
if (rankLhs < rankRhs) {
|
} else if (rankLhs > rankRhs) {
|
||||||
|
return 1;
|
||||||
|
} else {
|
||||||
|
// Same rank, so it's two contact records for the same contact.
|
||||||
|
// Perform secondary sorting on the phone type. Always place
|
||||||
|
// mobile before everything else.
|
||||||
|
final int phoneTypeLhs = (int) lhs[ContactUtil.INDEX_PHONE_EMAIL_TYPE];
|
||||||
|
final int phoneTypeRhs = (int) rhs[ContactUtil.INDEX_PHONE_EMAIL_TYPE];
|
||||||
|
if (phoneTypeLhs == Phone.TYPE_MOBILE &&
|
||||||
|
phoneTypeRhs == Phone.TYPE_MOBILE) {
|
||||||
|
return 0;
|
||||||
|
} else if (phoneTypeLhs == Phone.TYPE_MOBILE) {
|
||||||
return -1;
|
return -1;
|
||||||
} else if (rankLhs > rankRhs) {
|
} else if (phoneTypeRhs == Phone.TYPE_MOBILE) {
|
||||||
return 1;
|
return 1;
|
||||||
} else {
|
} else {
|
||||||
// Same rank, so it's two contact records for the same contact.
|
// Use the default sort order, i.e. sort by phoneType value.
|
||||||
// Perform secondary sorting on the phone type. Always place
|
return phoneTypeLhs < phoneTypeRhs ? -1 :
|
||||||
// mobile before everything else.
|
(phoneTypeLhs == phoneTypeRhs ? 0 : 1);
|
||||||
final int phoneTypeLhs = (int) lhs[ContactUtil.INDEX_PHONE_EMAIL_TYPE];
|
|
||||||
final int phoneTypeRhs = (int) rhs[ContactUtil.INDEX_PHONE_EMAIL_TYPE];
|
|
||||||
if (phoneTypeLhs == Phone.TYPE_MOBILE &&
|
|
||||||
phoneTypeRhs == Phone.TYPE_MOBILE) {
|
|
||||||
return 0;
|
|
||||||
} else if (phoneTypeLhs == Phone.TYPE_MOBILE) {
|
|
||||||
return -1;
|
|
||||||
} else if (phoneTypeRhs == Phone.TYPE_MOBILE) {
|
|
||||||
return 1;
|
|
||||||
} else {
|
|
||||||
// Use the default sort order, i.e. sort by phoneType value.
|
|
||||||
return phoneTypeLhs < phoneTypeRhs ? -1 :
|
|
||||||
(phoneTypeLhs == phoneTypeRhs ? 0 : 1);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -96,20 +96,13 @@ public class ParticipantRefresh {
|
|||||||
private static volatile boolean sObserverInitialized = false;
|
private static volatile boolean sObserverInitialized = false;
|
||||||
private static final Object sLock = new Object();
|
private static final Object sLock = new Object();
|
||||||
private static final AtomicBoolean sFullRefreshScheduled = new AtomicBoolean(false);
|
private static final AtomicBoolean sFullRefreshScheduled = new AtomicBoolean(false);
|
||||||
private static final Runnable sFullRefreshRunnable = new Runnable() {
|
private static final Runnable sFullRefreshRunnable = () -> {
|
||||||
@Override
|
final boolean oldScheduled = sFullRefreshScheduled.getAndSet(false);
|
||||||
public void run() {
|
Assert.isTrue(oldScheduled);
|
||||||
final boolean oldScheduled = sFullRefreshScheduled.getAndSet(false);
|
refreshParticipants(REFRESH_MODE_FULL);
|
||||||
Assert.isTrue(oldScheduled);
|
|
||||||
refreshParticipants(REFRESH_MODE_FULL);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
private static final Runnable sSelfOnlyRefreshRunnable = new Runnable() {
|
private static final Runnable sSelfOnlyRefreshRunnable = () ->
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
refreshParticipants(REFRESH_MODE_SELF_ONLY);
|
refreshParticipants(REFRESH_MODE_SELF_ONLY);
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A customized content resolver to track contact changes.
|
* A customized content resolver to track contact changes.
|
||||||
|
|||||||
@@ -303,24 +303,21 @@ public class ActionMonitor {
|
|||||||
}
|
}
|
||||||
if (completedListener != null) {
|
if (completedListener != null) {
|
||||||
// Marshal to UI thread
|
// Marshal to UI thread
|
||||||
mHandler.post(new Runnable() {
|
mHandler.post(() -> {
|
||||||
@Override
|
ActionCompletedListener listener = null;
|
||||||
public void run() {
|
synchronized (mLock) {
|
||||||
ActionCompletedListener listener = null;
|
if (mCompletedListener != null) {
|
||||||
synchronized (mLock) {
|
listener = mCompletedListener;
|
||||||
if (mCompletedListener != null) {
|
|
||||||
listener = mCompletedListener;
|
|
||||||
}
|
|
||||||
mCompletedListener = null;
|
|
||||||
}
|
}
|
||||||
if (listener != null) {
|
mCompletedListener = null;
|
||||||
if (succeeded) {
|
}
|
||||||
listener.onActionSucceeded(ActionMonitor.this,
|
if (listener != null) {
|
||||||
action, mData, result);
|
if (succeeded) {
|
||||||
} else {
|
listener.onActionSucceeded(ActionMonitor.this,
|
||||||
listener.onActionFailed(ActionMonitor.this,
|
action, mData, result);
|
||||||
action, mData, result);
|
} else {
|
||||||
}
|
listener.onActionFailed(ActionMonitor.this,
|
||||||
|
action, mData, result);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -372,21 +369,18 @@ public class ActionMonitor {
|
|||||||
}
|
}
|
||||||
if (executedListener != null) {
|
if (executedListener != null) {
|
||||||
// Marshal to UI thread
|
// Marshal to UI thread
|
||||||
mHandler.post(new Runnable() {
|
mHandler.post(() -> {
|
||||||
@Override
|
ActionExecutedListener listener = null;
|
||||||
public void run() {
|
synchronized (mLock) {
|
||||||
ActionExecutedListener listener = null;
|
if (mExecutedListener != null) {
|
||||||
synchronized (mLock) {
|
listener = mExecutedListener;
|
||||||
if (mExecutedListener != null) {
|
mExecutedListener = null;
|
||||||
listener = mExecutedListener;
|
|
||||||
mExecutedListener = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (listener != null) {
|
|
||||||
listener.onActionExecuted(ActionMonitor.this,
|
|
||||||
action, mData, result);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (listener != null) {
|
||||||
|
listener.onActionExecuted(ActionMonitor.this,
|
||||||
|
action, mData, result);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2015 The Android Open Source Project
|
* Copyright (C) 2015 The Android Open Source Project
|
||||||
|
* Copyright (C) 2024 The LineageOS Project
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -117,22 +118,13 @@ public class BugleActionToasts {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static void showToast(final int messageResId) {
|
private static void showToast(final int messageResId) {
|
||||||
ThreadUtil.getMainThreadHandler().post(new Runnable() {
|
ThreadUtil.getMainThreadHandler().post(() -> Toast.makeText(getApplicationContext(),
|
||||||
@Override
|
getApplicationContext().getString(messageResId), Toast.LENGTH_LONG).show());
|
||||||
public void run() {
|
|
||||||
Toast.makeText(getApplicationContext(),
|
|
||||||
getApplicationContext().getString(messageResId), Toast.LENGTH_LONG).show();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void showToast(final String message) {
|
private static void showToast(final String message) {
|
||||||
ThreadUtil.getMainThreadHandler().post(new Runnable() {
|
ThreadUtil.getMainThreadHandler().post(() ->
|
||||||
@Override
|
Toast.makeText(getApplicationContext(), message, Toast.LENGTH_LONG).show());
|
||||||
public void run() {
|
|
||||||
Toast.makeText(getApplicationContext(), message, Toast.LENGTH_LONG).show();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Context getApplicationContext() {
|
private static Context getApplicationContext() {
|
||||||
|
|||||||
@@ -61,18 +61,15 @@ public class ProcessPendingMessagesAction extends Action implements Parcelable {
|
|||||||
private static final String KEY_SUB_ID = "sub_id";
|
private static final String KEY_SUB_ID = "sub_id";
|
||||||
|
|
||||||
public static void processFirstPendingMessage() {
|
public static void processFirstPendingMessage() {
|
||||||
PhoneUtils.forEachActiveSubscription(new PhoneUtils.SubscriptionRunnable() {
|
PhoneUtils.forEachActiveSubscription(subId -> {
|
||||||
@Override
|
// Clear any pending alarms or connectivity events
|
||||||
public void runForSubscription(final int subId) {
|
unregister(subId);
|
||||||
// Clear any pending alarms or connectivity events
|
// Clear retry count
|
||||||
unregister(subId);
|
setRetry(0, subId);
|
||||||
// Clear retry count
|
// Start action
|
||||||
setRetry(0, subId);
|
final ProcessPendingMessagesAction action = new ProcessPendingMessagesAction();
|
||||||
// Start action
|
action.actionParameters.putInt(KEY_SUB_ID, subId);
|
||||||
final ProcessPendingMessagesAction action = new ProcessPendingMessagesAction();
|
action.start();
|
||||||
action.actionParameters.putInt(KEY_SUB_ID, subId);
|
|
||||||
action.start();
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -114,23 +111,20 @@ public class ProcessPendingMessagesAction extends Action implements Parcelable {
|
|||||||
}
|
}
|
||||||
if (getHavePendingMessages(subId) || scheduleAlarm) {
|
if (getHavePendingMessages(subId) || scheduleAlarm) {
|
||||||
// Still have a pending message that needs to be queued for processing
|
// Still have a pending message that needs to be queued for processing
|
||||||
final ConnectivityListener listener = new ConnectivityListener() {
|
final ConnectivityListener listener = serviceState -> {
|
||||||
@Override
|
if (serviceState == ServiceState.STATE_IN_SERVICE) {
|
||||||
public void onPhoneStateChanged(final int serviceState) {
|
LogUtil.i(TAG, "ProcessPendingMessagesAction: Now connected for subId "
|
||||||
if (serviceState == ServiceState.STATE_IN_SERVICE) {
|
+ subId + ", starting action");
|
||||||
LogUtil.i(TAG, "ProcessPendingMessagesAction: Now connected for subId "
|
|
||||||
+ subId + ", starting action");
|
|
||||||
|
|
||||||
// Clear any pending alarms or connectivity events but leave attempt count
|
// Clear any pending alarms or connectivity events but leave attempt count
|
||||||
// alone
|
// alone
|
||||||
unregister(subId);
|
unregister(subId);
|
||||||
|
|
||||||
// Start action
|
// Start action
|
||||||
final ProcessPendingMessagesAction action =
|
final ProcessPendingMessagesAction action =
|
||||||
new ProcessPendingMessagesAction();
|
new ProcessPendingMessagesAction();
|
||||||
action.actionParameters.putInt(KEY_SUB_ID, subId);
|
action.actionParameters.putInt(KEY_SUB_ID, subId);
|
||||||
action.start();
|
action.start();
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
// Read and increment attempt number from shared prefs
|
// Read and increment attempt number from shared prefs
|
||||||
|
|||||||
@@ -627,21 +627,18 @@ public class ConversationData extends BindableData {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (ContactUtil.hasReadContactsPermission()) {
|
if (ContactUtil.hasReadContactsPermission()) {
|
||||||
SafeAsyncTask.executeOnThreadPool(new Runnable() {
|
SafeAsyncTask.executeOnThreadPool(() -> {
|
||||||
@Override
|
final DataUsageStatUpdater updater = new DataUsageStatUpdater(
|
||||||
public void run() {
|
Factory.get().getApplicationContext());
|
||||||
final DataUsageStatUpdater updater = new DataUsageStatUpdater(
|
try {
|
||||||
Factory.get().getApplicationContext());
|
if (!phones.isEmpty()) {
|
||||||
try {
|
updater.updateWithPhoneNumber(phones);
|
||||||
if (!phones.isEmpty()) {
|
|
||||||
updater.updateWithPhoneNumber(phones);
|
|
||||||
}
|
|
||||||
if (!emails.isEmpty()) {
|
|
||||||
updater.updateWithAddress(emails);
|
|
||||||
}
|
|
||||||
} catch (final SQLiteFullException ex) {
|
|
||||||
LogUtil.w(TAG, "Unable to update contact", ex);
|
|
||||||
}
|
}
|
||||||
|
if (!emails.isEmpty()) {
|
||||||
|
updater.updateWithAddress(emails);
|
||||||
|
}
|
||||||
|
} catch (final SQLiteFullException ex) {
|
||||||
|
LogUtil.w(TAG, "Unable to update contact", ex);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -445,13 +445,9 @@ public class MessagePartData implements Parcelable {
|
|||||||
public void destroyAsync() {
|
public void destroyAsync() {
|
||||||
final Uri contentUri = shouldDestroy();
|
final Uri contentUri = shouldDestroy();
|
||||||
if (contentUri != null) {
|
if (contentUri != null) {
|
||||||
SafeAsyncTask.executeOnThreadPool(new Runnable() {
|
SafeAsyncTask.executeOnThreadPool(() ->
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
Factory.get().getApplicationContext().getContentResolver().delete(
|
Factory.get().getApplicationContext().getContentResolver().delete(
|
||||||
contentUri, null, null);
|
contentUri, null, null));
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2015 The Android Open Source Project
|
* Copyright (C) 2015 The Android Open Source Project
|
||||||
|
* Copyright (C) 2024 The LineageOS Project
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -20,7 +21,6 @@ import android.database.Cursor;
|
|||||||
import androidx.collection.ArrayMap;
|
import androidx.collection.ArrayMap;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@@ -61,15 +61,11 @@ public class SelfParticipantsData {
|
|||||||
list.add(self);
|
list.add(self);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Collections.sort(
|
list.sort((Comparator) (o1, o2) -> {
|
||||||
list,
|
int slotId1 = ((ParticipantData) o1).getSlotId();
|
||||||
new Comparator() {
|
int slotId2 = ((ParticipantData) o2).getSlotId();
|
||||||
public int compare(Object o1, Object o2) {
|
return slotId1 > slotId2 ? 1 : -1;
|
||||||
int slotId1 = ((ParticipantData) o1).getSlotId();
|
});
|
||||||
int slotId2 = ((ParticipantData) o2).getSlotId();
|
|
||||||
return slotId1 > slotId2 ? 1 : -1;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2015 The Android Open Source Project
|
* Copyright (C) 2015 The Android Open Source Project
|
||||||
|
* Copyright (C) 2024 The LineageOS Project
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -27,7 +28,6 @@ import java.util.ArrayList;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.Executor;
|
import java.util.concurrent.Executor;
|
||||||
import java.util.concurrent.Executors;
|
import java.util.concurrent.Executors;
|
||||||
import java.util.concurrent.ThreadFactory;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>Loads and maintains a set of in-memory LRU caches for different types of media resources.
|
* <p>Loads and maintains a set of in-memory LRU caches for different types of media resources.
|
||||||
@@ -104,13 +104,10 @@ public class MediaResourceManager {
|
|||||||
// These tasks are run on a single worker thread with low priority so as not to contend with the
|
// These tasks are run on a single worker thread with low priority so as not to contend with the
|
||||||
// media loading tasks.
|
// media loading tasks.
|
||||||
private static final Executor MEDIA_BACKGROUND_EXECUTOR = Executors.newSingleThreadExecutor(
|
private static final Executor MEDIA_BACKGROUND_EXECUTOR = Executors.newSingleThreadExecutor(
|
||||||
new ThreadFactory() {
|
runnable -> {
|
||||||
@Override
|
final Thread encodingThread = new Thread(runnable);
|
||||||
public Thread newThread(final Runnable runnable) {
|
encodingThread.setPriority(Thread.MIN_PRIORITY);
|
||||||
final Thread encodingThread = new Thread(runnable);
|
return encodingThread;
|
||||||
encodingThread.setPriority(Thread.MIN_PRIORITY);
|
|
||||||
return encodingThread;
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2015 The Android Open Source Project
|
* Copyright (C) 2015 The Android Open Source Project
|
||||||
|
* Copyright (C) 2024 The LineageOS Project
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -71,13 +72,9 @@ public class VCardResourceEntry {
|
|||||||
void close() {
|
void close() {
|
||||||
// If the avatar image was temporarily saved in the scratch folder, remove that.
|
// If the avatar image was temporarily saved in the scratch folder, remove that.
|
||||||
if (MediaScratchFileProvider.isMediaScratchSpaceUri(mAvatarUri)) {
|
if (MediaScratchFileProvider.isMediaScratchSpaceUri(mAvatarUri)) {
|
||||||
SafeAsyncTask.executeOnThreadPool(new Runnable() {
|
SafeAsyncTask.executeOnThreadPool(() ->
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
Factory.get().getApplicationContext().getContentResolver().delete(
|
Factory.get().getApplicationContext().getContentResolver().delete(
|
||||||
mAvatarUri, null, null);
|
mAvatarUri, null, null));
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2015 The Android Open Source Project
|
* Copyright (C) 2015 The Android Open Source Project
|
||||||
|
* Copyright (C) 2024 The LineageOS Project
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -336,12 +337,8 @@ public class ApnDatabase extends SQLiteOpenHelper {
|
|||||||
final Resources r = sContext.getResources();
|
final Resources r = sContext.getResources();
|
||||||
final XmlResourceParser parser = r.getXml(R.xml.apns);
|
final XmlResourceParser parser = r.getXml(R.xml.apns);
|
||||||
final ApnsXmlProcessor processor = ApnsXmlProcessor.get(parser);
|
final ApnsXmlProcessor processor = ApnsXmlProcessor.get(parser);
|
||||||
processor.setApnHandler(new ApnsXmlProcessor.ApnHandler() {
|
processor.setApnHandler(apnValues -> db.insert(APN_TABLE, null/*nullColumnHack*/,
|
||||||
@Override
|
apnValues));
|
||||||
public void process(final ContentValues apnValues) {
|
|
||||||
db.insert(APN_TABLE, null/*nullColumnHack*/, apnValues);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
try {
|
try {
|
||||||
processor.process();
|
processor.process();
|
||||||
} catch (final Exception e) {
|
} catch (final Exception e) {
|
||||||
|
|||||||
@@ -129,13 +129,8 @@ public class BugleCarrierConfigValuesLoader implements CarrierConfigValuesLoader
|
|||||||
try {
|
try {
|
||||||
parser = subContext.getResources().getXml(R.xml.mms_config);
|
parser = subContext.getResources().getXml(R.xml.mms_config);
|
||||||
final ApnsXmlProcessor processor = ApnsXmlProcessor.get(parser);
|
final ApnsXmlProcessor processor = ApnsXmlProcessor.get(parser);
|
||||||
processor.setMmsConfigHandler(new ApnsXmlProcessor.MmsConfigHandler() {
|
processor.setMmsConfigHandler((mccMnc, key, value, type) ->
|
||||||
@Override
|
update(values, type, key, value));
|
||||||
public void process(final String mccMnc, final String key, final String value,
|
|
||||||
final String type) {
|
|
||||||
update(values, type, key, value);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
processor.process();
|
processor.process();
|
||||||
} catch (final Resources.NotFoundException e) {
|
} catch (final Resources.NotFoundException e) {
|
||||||
LogUtil.w(LogUtil.BUGLE_TAG, "Can not find mms_config.xml");
|
LogUtil.w(LogUtil.BUGLE_TAG, "Can not find mms_config.xml");
|
||||||
|
|||||||
@@ -134,12 +134,7 @@ public class MmsConfig {
|
|||||||
* Same as load() but doing it using an async thread from SafeAsyncTask thread pool.
|
* Same as load() but doing it using an async thread from SafeAsyncTask thread pool.
|
||||||
*/
|
*/
|
||||||
public static void loadAsync() {
|
public static void loadAsync() {
|
||||||
SafeAsyncTask.executeOnThreadPool(new Runnable() {
|
SafeAsyncTask.executeOnThreadPool(MmsConfig::load);
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
load();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -85,7 +85,7 @@ public class AsyncImageView extends ImageView implements MediaResourceLoadListen
|
|||||||
// setting is null (no placeholder).
|
// setting is null (no placeholder).
|
||||||
private final Drawable mPlaceholderDrawable;
|
private final Drawable mPlaceholderDrawable;
|
||||||
protected ImageResource mImageResource;
|
protected ImageResource mImageResource;
|
||||||
private final Runnable mDisposeRunnable = new Runnable() {
|
private final Runnable mDisposeRunnable = () -> new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
if (mImageRequestBinding.isBound()) {
|
if (mImageRequestBinding.isBound()) {
|
||||||
|
|||||||
@@ -71,35 +71,22 @@ public class AttachmentPreview extends ScrollView implements OnAttachmentClickLi
|
|||||||
protected void onFinishInflate() {
|
protected void onFinishInflate() {
|
||||||
super.onFinishInflate();
|
super.onFinishInflate();
|
||||||
mCloseButton = (ImageButton) findViewById(R.id.close_button);
|
mCloseButton = (ImageButton) findViewById(R.id.close_button);
|
||||||
mCloseButton.setOnClickListener(new OnClickListener() {
|
mCloseButton.setOnClickListener(view -> mComposeMessageView.clearAttachments());
|
||||||
@Override
|
|
||||||
public void onClick(final View view) {
|
|
||||||
mComposeMessageView.clearAttachments();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
mAttachmentView = (FrameLayout) findViewById(R.id.attachment_view);
|
mAttachmentView = (FrameLayout) findViewById(R.id.attachment_view);
|
||||||
|
|
||||||
// The attachment preview is a scroll view so that it can show the bottom portion of the
|
// The attachment preview is a scroll view so that it can show the bottom portion of the
|
||||||
// attachment whenever the space is tight (e.g. when in landscape mode). Per design
|
// attachment whenever the space is tight (e.g. when in landscape mode). Per design
|
||||||
// request we'd like to make the attachment view always scrolled to the bottom.
|
// request we'd like to make the attachment view always scrolled to the bottom.
|
||||||
addOnLayoutChangeListener(new OnLayoutChangeListener() {
|
addOnLayoutChangeListener((v, left, top, right, bottom, oldLeft, oldTop, oldRight,
|
||||||
@Override
|
oldBottom) -> post(() ->
|
||||||
public void onLayoutChange(final View v, final int left, final int top, final int right,
|
{
|
||||||
final int bottom, final int oldLeft, final int oldTop, final int oldRight,
|
final int childCount = getChildCount();
|
||||||
final int oldBottom) {
|
if (childCount > 0) {
|
||||||
post(new Runnable() {
|
final View lastChild = getChildAt(childCount - 1);
|
||||||
@Override
|
scrollTo(getScrollX(), lastChild.getBottom() - getHeight());
|
||||||
public void run() {
|
|
||||||
final int childCount = getChildCount();
|
|
||||||
if (childCount > 0) {
|
|
||||||
final View lastChild = getChildAt(childCount - 1);
|
|
||||||
scrollTo(getScrollX(), lastChild.getBottom() - getHeight());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
});
|
}));
|
||||||
mPendingFirstUpdate = true;
|
mPendingFirstUpdate = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -129,18 +116,14 @@ public class AttachmentPreview extends ScrollView implements OnAttachmentClickLi
|
|||||||
mPendingHideCanceled = false;
|
mPendingHideCanceled = false;
|
||||||
final View viewToHide = mAttachmentView.getChildCount() > 1 ?
|
final View viewToHide = mAttachmentView.getChildCount() > 1 ?
|
||||||
mAttachmentView : mAttachmentView.getChildAt(0);
|
mAttachmentView : mAttachmentView.getChildAt(0);
|
||||||
UiUtils.revealOrHideViewWithAnimation(viewToHide, INVISIBLE,
|
UiUtils.revealOrHideViewWithAnimation(viewToHide, INVISIBLE, () -> {
|
||||||
new Runnable() {
|
// Only hide if we are didn't get overruled by showing
|
||||||
@Override
|
if (!mPendingHideCanceled) {
|
||||||
public void run() {
|
stopPopupAnimation();
|
||||||
// Only hide if we are didn't get overruled by showing
|
mAttachmentView.removeAllViews();
|
||||||
if (!mPendingHideCanceled) {
|
setVisibility(GONE);
|
||||||
stopPopupAnimation();
|
}
|
||||||
mAttachmentView.removeAllViews();
|
});
|
||||||
setVisibility(GONE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} else {
|
} else {
|
||||||
mAttachmentView.removeAllViews();
|
mAttachmentView.removeAllViews();
|
||||||
setVisibility(GONE);
|
setVisibility(GONE);
|
||||||
@@ -164,14 +147,11 @@ public class AttachmentPreview extends ScrollView implements OnAttachmentClickLi
|
|||||||
.getQuantityString(R.plurals.attachment_preview_close_content_description,
|
.getQuantityString(R.plurals.attachment_preview_close_content_description,
|
||||||
combinedAttachmentCount));
|
combinedAttachmentCount));
|
||||||
if (combinedAttachmentCount == 0) {
|
if (combinedAttachmentCount == 0) {
|
||||||
mHideRunnable = new Runnable() {
|
mHideRunnable = () -> {
|
||||||
@Override
|
mHideRunnable = null;
|
||||||
public void run() {
|
// Only start the hiding if there are still no attachments
|
||||||
mHideRunnable = null;
|
if (attachments.size() + pendingAttachments.size() == 0) {
|
||||||
// Only start the hiding if there are still no attachments
|
hideAttachmentPreview();
|
||||||
if (attachments.size() + pendingAttachments.size() == 0) {
|
|
||||||
hideAttachmentPreview();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
if (draftMessageData.isSending()) {
|
if (draftMessageData.isSending()) {
|
||||||
@@ -196,13 +176,11 @@ public class AttachmentPreview extends ScrollView implements OnAttachmentClickLi
|
|||||||
if (!isFirstUpdate) {
|
if (!isFirstUpdate) {
|
||||||
// Reveal the close button after the view animates in.
|
// Reveal the close button after the view animates in.
|
||||||
mCloseButton.setVisibility(INVISIBLE);
|
mCloseButton.setVisibility(INVISIBLE);
|
||||||
ThreadUtil.getMainThreadHandler().postDelayed(new Runnable() {
|
ThreadUtil.getMainThreadHandler().postDelayed(() ->
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
UiUtils.revealOrHideViewWithAnimation(mCloseButton, VISIBLE,
|
UiUtils.revealOrHideViewWithAnimation(mCloseButton, VISIBLE,
|
||||||
null /* onFinishRunnable */);
|
null /* onFinishRunnable */),
|
||||||
}
|
UiUtils.MEDIAPICKER_TRANSITION_DURATION +
|
||||||
}, UiUtils.MEDIAPICKER_TRANSITION_DURATION + CLOSE_BUTTON_REVEAL_STAGGER_MILLIS);
|
CLOSE_BUTTON_REVEAL_STAGGER_MILLIS);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2015 The Android Open Source Project
|
* Copyright (C) 2015 The Android Open Source Project
|
||||||
|
* Copyright (C) 2024 The LineageOS Project
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -23,8 +24,6 @@ import androidx.annotation.Nullable;
|
|||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.View.OnClickListener;
|
|
||||||
import android.view.View.OnLongClickListener;
|
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.widget.FrameLayout.LayoutParams;
|
import android.widget.FrameLayout.LayoutParams;
|
||||||
import android.widget.ImageView;
|
import android.widget.ImageView;
|
||||||
@@ -93,22 +92,16 @@ public class AttachmentPreviewFactory {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (attachmentView != null && clickListener != null) {
|
if (attachmentView != null && clickListener != null) {
|
||||||
attachmentView.setOnClickListener(new OnClickListener() {
|
attachmentView.setOnClickListener(view -> {
|
||||||
@Override
|
final Rect bounds = UiUtils.getMeasuredBoundsOnScreen(view);
|
||||||
public void onClick(final View view) {
|
clickListener.onAttachmentClick(attachmentData, bounds,
|
||||||
final Rect bounds = UiUtils.getMeasuredBoundsOnScreen(view);
|
false /* longPress */);
|
||||||
clickListener.onAttachmentClick(attachmentData, bounds,
|
});
|
||||||
false /* longPress */);
|
attachmentView.setOnLongClickListener(view -> {
|
||||||
}
|
final Rect bounds = UiUtils.getMeasuredBoundsOnScreen(view);
|
||||||
});
|
return clickListener.onAttachmentClick(attachmentData, bounds,
|
||||||
attachmentView.setOnLongClickListener(new OnLongClickListener() {
|
true /* longPress */);
|
||||||
@Override
|
});
|
||||||
public boolean onLongClick(final View view) {
|
|
||||||
final Rect bounds = UiUtils.getMeasuredBoundsOnScreen(view);
|
|
||||||
return clickListener.onAttachmentClick(attachmentData, bounds,
|
|
||||||
true /* longPress */);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
return attachmentView;
|
return attachmentView;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2015 The Android Open Source Project
|
* Copyright (C) 2015 The Android Open Source Project
|
||||||
|
* Copyright (C) 2024 The LineageOS Project
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -22,9 +23,6 @@ import android.graphics.Path;
|
|||||||
import android.graphics.RectF;
|
import android.graphics.RectF;
|
||||||
import android.media.AudioManager;
|
import android.media.AudioManager;
|
||||||
import android.media.MediaPlayer;
|
import android.media.MediaPlayer;
|
||||||
import android.media.MediaPlayer.OnCompletionListener;
|
|
||||||
import android.media.MediaPlayer.OnErrorListener;
|
|
||||||
import android.media.MediaPlayer.OnPreparedListener;
|
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.SystemClock;
|
import android.os.SystemClock;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
@@ -106,32 +104,29 @@ public class AudioAttachmentView extends LinearLayout {
|
|||||||
mPlayPauseButton = (AudioAttachmentPlayPauseButton) findViewById(R.id.play_pause_button);
|
mPlayPauseButton = (AudioAttachmentPlayPauseButton) findViewById(R.id.play_pause_button);
|
||||||
mChronometer = (PausableChronometer) findViewById(R.id.timer);
|
mChronometer = (PausableChronometer) findViewById(R.id.timer);
|
||||||
mProgressBar = (AudioPlaybackProgressBar) findViewById(R.id.progress);
|
mProgressBar = (AudioPlaybackProgressBar) findViewById(R.id.progress);
|
||||||
mPlayPauseButton.setOnClickListener(new OnClickListener() {
|
mPlayPauseButton.setOnClickListener(v -> {
|
||||||
@Override
|
// Has the MediaPlayer already been prepared?
|
||||||
public void onClick(final View v) {
|
if (mMediaPlayer != null && mPrepared) {
|
||||||
// Has the MediaPlayer already been prepared?
|
if (mMediaPlayer.isPlaying()) {
|
||||||
if (mMediaPlayer != null && mPrepared) {
|
mMediaPlayer.pause();
|
||||||
if (mMediaPlayer.isPlaying()) {
|
mChronometer.pause();
|
||||||
mMediaPlayer.pause();
|
mProgressBar.pause();
|
||||||
mChronometer.pause();
|
|
||||||
mProgressBar.pause();
|
|
||||||
} else {
|
|
||||||
playAudio();
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
// Either eager preparation is still going on (the user must have clicked
|
playAudio();
|
||||||
// the Play button immediately after the view is bound) or this is lazy
|
}
|
||||||
// preparation.
|
} else {
|
||||||
if (mStartPlayAfterPrepare) {
|
// Either eager preparation is still going on (the user must have clicked
|
||||||
// The user is (starting and) pausing before the MediaPlayer is prepared
|
// the Play button immediately after the view is bound) or this is lazy
|
||||||
mStartPlayAfterPrepare = false;
|
// preparation.
|
||||||
} else {
|
if (mStartPlayAfterPrepare) {
|
||||||
mStartPlayAfterPrepare = true;
|
// The user is (starting and) pausing before the MediaPlayer is prepared
|
||||||
setupMediaPlayer();
|
mStartPlayAfterPrepare = false;
|
||||||
}
|
} else {
|
||||||
|
mStartPlayAfterPrepare = true;
|
||||||
|
setupMediaPlayer();
|
||||||
}
|
}
|
||||||
updatePlayPauseButtonState();
|
|
||||||
}
|
}
|
||||||
|
updatePlayPauseButtonState();
|
||||||
});
|
});
|
||||||
updatePlayPauseButtonState();
|
updatePlayPauseButtonState();
|
||||||
initializeViewsForMode();
|
initializeViewsForMode();
|
||||||
@@ -217,47 +212,38 @@ public class AudioAttachmentView extends LinearLayout {
|
|||||||
try {
|
try {
|
||||||
mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
|
mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
|
||||||
mMediaPlayer.setDataSource(Factory.get().getApplicationContext(), mDataSourceUri);
|
mMediaPlayer.setDataSource(Factory.get().getApplicationContext(), mDataSourceUri);
|
||||||
mMediaPlayer.setOnCompletionListener(new OnCompletionListener() {
|
mMediaPlayer.setOnCompletionListener(mp -> {
|
||||||
@Override
|
updatePlayPauseButtonState();
|
||||||
public void onCompletion(final MediaPlayer mp) {
|
mChronometer.reset();
|
||||||
updatePlayPauseButtonState();
|
mChronometer.setBase(SystemClock.elapsedRealtime() -
|
||||||
mChronometer.reset();
|
mMediaPlayer.getDuration());
|
||||||
mChronometer.setBase(SystemClock.elapsedRealtime() -
|
updateChronometerVisibility(false /* playing */);
|
||||||
mMediaPlayer.getDuration());
|
mProgressBar.reset();
|
||||||
updateChronometerVisibility(false /* playing */);
|
|
||||||
mProgressBar.reset();
|
|
||||||
|
|
||||||
mPlaybackFinished = true;
|
mPlaybackFinished = true;
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
mMediaPlayer.setOnPreparedListener(new OnPreparedListener() {
|
mMediaPlayer.setOnPreparedListener(mp -> {
|
||||||
@Override
|
// Set base on the chronometer so we can show the full length of the audio.
|
||||||
public void onPrepared(final MediaPlayer mp) {
|
mChronometer.setBase(SystemClock.elapsedRealtime() -
|
||||||
// Set base on the chronometer so we can show the full length of the audio.
|
mMediaPlayer.getDuration());
|
||||||
mChronometer.setBase(SystemClock.elapsedRealtime() -
|
mProgressBar.setDuration(mMediaPlayer.getDuration());
|
||||||
mMediaPlayer.getDuration());
|
mMediaPlayer.seekTo(0);
|
||||||
mProgressBar.setDuration(mMediaPlayer.getDuration());
|
mPrepared = true;
|
||||||
mMediaPlayer.seekTo(0);
|
|
||||||
mPrepared = true;
|
|
||||||
|
|
||||||
if (mStartPlayAfterPrepare) {
|
if (mStartPlayAfterPrepare) {
|
||||||
mStartPlayAfterPrepare = false;
|
|
||||||
playAudio();
|
|
||||||
updatePlayPauseButtonState();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
mMediaPlayer.setOnErrorListener(new OnErrorListener() {
|
|
||||||
@Override
|
|
||||||
public boolean onError(final MediaPlayer mp, final int what, final int extra) {
|
|
||||||
mStartPlayAfterPrepare = false;
|
mStartPlayAfterPrepare = false;
|
||||||
onAudioReplayError(what, extra, null);
|
playAudio();
|
||||||
return true;
|
updatePlayPauseButtonState();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
mMediaPlayer.setOnErrorListener((mp, what, extra) -> {
|
||||||
|
mStartPlayAfterPrepare = false;
|
||||||
|
onAudioReplayError(what, extra, null);
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
|
||||||
mMediaPlayer.prepareAsync();
|
mMediaPlayer.prepareAsync();
|
||||||
} catch (final Exception exception) {
|
} catch (final Exception exception) {
|
||||||
onAudioReplayError(0, 0, exception);
|
onAudioReplayError(0, 0, exception);
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2015 The Android Open Source Project
|
* Copyright (C) 2015 The Android Open Source Project
|
||||||
|
* Copyright (C) 2024 The LineageOS Project
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -17,7 +18,6 @@ package com.android.messaging.ui;
|
|||||||
|
|
||||||
import android.animation.ObjectAnimator;
|
import android.animation.ObjectAnimator;
|
||||||
import android.animation.TimeAnimator;
|
import android.animation.TimeAnimator;
|
||||||
import android.animation.TimeAnimator.TimeListener;
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.graphics.drawable.ClipDrawable;
|
import android.graphics.drawable.ClipDrawable;
|
||||||
import android.graphics.drawable.Drawable;
|
import android.graphics.drawable.Drawable;
|
||||||
@@ -41,18 +41,14 @@ public class AudioPlaybackProgressBar extends ProgressBar implements PlaybackSta
|
|||||||
|
|
||||||
mUpdateAnimator = new TimeAnimator();
|
mUpdateAnimator = new TimeAnimator();
|
||||||
mUpdateAnimator.setRepeatCount(ObjectAnimator.INFINITE);
|
mUpdateAnimator.setRepeatCount(ObjectAnimator.INFINITE);
|
||||||
mUpdateAnimator.setTimeListener(new TimeListener() {
|
mUpdateAnimator.setTimeListener((animation, totalTime, deltaTime) -> {
|
||||||
@Override
|
int progress = 0;
|
||||||
public void onTimeUpdate(final TimeAnimator animation, final long totalTime,
|
if (mDurationInMillis > 0) {
|
||||||
final long deltaTime) {
|
progress = (int) (((mCumulativeTime + SystemClock.elapsedRealtime() -
|
||||||
int progress = 0;
|
mCurrentPlayStartTime) * 1.0f / mDurationInMillis) * 100);
|
||||||
if (mDurationInMillis > 0) {
|
progress = Math.max(Math.min(progress, 100), 0);
|
||||||
progress = (int) (((mCumulativeTime + SystemClock.elapsedRealtime() -
|
|
||||||
mCurrentPlayStartTime) * 1.0f / mDurationInMillis) * 100);
|
|
||||||
progress = Math.max(Math.min(progress, 100), 0);
|
|
||||||
}
|
|
||||||
setProgress(progress);
|
|
||||||
}
|
}
|
||||||
|
setProgress(progress);
|
||||||
});
|
});
|
||||||
updateAppearance();
|
updateAppearance();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2015 The Android Open Source Project
|
* Copyright (C) 2015 The Android Open Source Project
|
||||||
|
* Copyright (C) 2024 The LineageOS Project
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -19,7 +20,6 @@ import android.content.Context;
|
|||||||
import androidx.core.text.BidiFormatter;
|
import androidx.core.text.BidiFormatter;
|
||||||
import androidx.core.text.TextDirectionHeuristicsCompat;
|
import androidx.core.text.TextDirectionHeuristicsCompat;
|
||||||
import android.util.AttributeSet;
|
import android.util.AttributeSet;
|
||||||
import android.view.View;
|
|
||||||
import android.widget.LinearLayout;
|
import android.widget.LinearLayout;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
@@ -44,12 +44,7 @@ public class BlockedParticipantListItemView extends LinearLayout {
|
|||||||
protected void onFinishInflate() {
|
protected void onFinishInflate() {
|
||||||
mNameTextView = (TextView) findViewById(R.id.name);
|
mNameTextView = (TextView) findViewById(R.id.name);
|
||||||
mContactIconView = (ContactIconView) findViewById(R.id.contact_icon);
|
mContactIconView = (ContactIconView) findViewById(R.id.contact_icon);
|
||||||
setOnClickListener(new OnClickListener() {
|
setOnClickListener(v -> mData.unblock(getContext()));
|
||||||
@Override
|
|
||||||
public void onClick(final View v) {
|
|
||||||
mData.unblock(getContext());
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void bind(final ParticipantListItemData data) {
|
public void bind(final ParticipantListItemData data) {
|
||||||
|
|||||||
@@ -20,7 +20,6 @@ package com.android.messaging.ui;
|
|||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.app.AlertDialog;
|
import android.app.AlertDialog;
|
||||||
import android.content.ContentValues;
|
import android.content.ContentValues;
|
||||||
import android.content.DialogInterface;
|
|
||||||
import android.content.DialogInterface.OnClickListener;
|
import android.content.DialogInterface.OnClickListener;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
@@ -188,21 +187,15 @@ public class ClassZeroActivity extends Activity {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private final OnClickListener mCancelListener = new OnClickListener() {
|
private final OnClickListener mCancelListener = (dialog, whichButton) -> {
|
||||||
@Override
|
dialog.dismiss();
|
||||||
public void onClick(final DialogInterface dialog, final int whichButton) {
|
processNextMessage();
|
||||||
dialog.dismiss();
|
|
||||||
processNextMessage();
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
private final OnClickListener mSaveListener = new OnClickListener() {
|
private final OnClickListener mSaveListener = (dialog, whichButton) -> {
|
||||||
@Override
|
mRead = true;
|
||||||
public void onClick(final DialogInterface dialog, final int whichButton) {
|
saveMessage();
|
||||||
mRead = true;
|
dialog.dismiss();
|
||||||
saveMessage();
|
processNextMessage();
|
||||||
dialog.dismiss();
|
|
||||||
processNextMessage();
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2015 The Android Open Source Project
|
* Copyright (C) 2015 The Android Open Source Project
|
||||||
|
* Copyright (C) 2024 The LineageOS Project
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -22,7 +23,6 @@ import android.net.Uri;
|
|||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
import android.util.AttributeSet;
|
import android.util.AttributeSet;
|
||||||
import android.view.MotionEvent;
|
import android.view.MotionEvent;
|
||||||
import android.view.View;
|
|
||||||
|
|
||||||
import com.android.messaging.R;
|
import com.android.messaging.R;
|
||||||
import com.android.messaging.datamodel.data.ParticipantData;
|
import com.android.messaging.datamodel.data.ParticipantData;
|
||||||
@@ -134,13 +134,8 @@ public class ContactIconView extends AsyncImageView {
|
|||||||
&& !TextUtils.isEmpty(mContactLookupKey)) ||
|
&& !TextUtils.isEmpty(mContactLookupKey)) ||
|
||||||
!TextUtils.isEmpty(mNormalizedDestination)) {
|
!TextUtils.isEmpty(mNormalizedDestination)) {
|
||||||
if (!mDisableClickHandler) {
|
if (!mDisableClickHandler) {
|
||||||
setOnClickListener(new View.OnClickListener() {
|
setOnClickListener(view -> ContactUtil.showOrAddContact(view, mContactId,
|
||||||
@Override
|
mContactLookupKey, mAvatarUri, mNormalizedDestination));
|
||||||
public void onClick(final View view) {
|
|
||||||
ContactUtil.showOrAddContact(view, mContactId, mContactLookupKey,
|
|
||||||
mAvatarUri, mNormalizedDestination);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// This should happen when the phone number is not in the user's contacts or it is a
|
// This should happen when the phone number is not in the user's contacts or it is a
|
||||||
|
|||||||
@@ -24,7 +24,6 @@ import android.os.Bundle;
|
|||||||
import android.os.SystemClock;
|
import android.os.SystemClock;
|
||||||
import android.provider.Settings;
|
import android.provider.Settings;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.View.OnClickListener;
|
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
@@ -57,29 +56,16 @@ public class PermissionCheckActivity extends Activity {
|
|||||||
setContentView(R.layout.permission_check_activity);
|
setContentView(R.layout.permission_check_activity);
|
||||||
UiUtils.setStatusBarColor(this, getColor(R.color.permission_check_activity_background));
|
UiUtils.setStatusBarColor(this, getColor(R.color.permission_check_activity_background));
|
||||||
|
|
||||||
findViewById(R.id.exit).setOnClickListener(new OnClickListener() {
|
findViewById(R.id.exit).setOnClickListener(view -> finish());
|
||||||
@Override
|
|
||||||
public void onClick(final View view) {
|
|
||||||
finish();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
mNextView = (TextView) findViewById(R.id.next);
|
mNextView = (TextView) findViewById(R.id.next);
|
||||||
mNextView.setOnClickListener(new OnClickListener() {
|
mNextView.setOnClickListener(view -> tryRequestPermission());
|
||||||
@Override
|
|
||||||
public void onClick(final View view) {
|
|
||||||
tryRequestPermission();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
mSettingsView = (TextView) findViewById(R.id.settings);
|
mSettingsView = (TextView) findViewById(R.id.settings);
|
||||||
mSettingsView.setOnClickListener(new OnClickListener() {
|
mSettingsView.setOnClickListener(view -> {
|
||||||
@Override
|
final Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS,
|
||||||
public void onClick(final View view) {
|
Uri.parse(PACKAGE_URI_PREFIX + getPackageName()));
|
||||||
final Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS,
|
startActivity(intent);
|
||||||
Uri.parse(PACKAGE_URI_PREFIX + getPackageName()));
|
|
||||||
startActivity(intent);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2015 The Android Open Source Project
|
* Copyright (C) 2015 The Android Open Source Project
|
||||||
|
* Copyright (C) 2024 The LineageOS Project
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -168,22 +169,16 @@ public class PersonItemView extends LinearLayout implements PersonItemDataListen
|
|||||||
if (mListener == null) {
|
if (mListener == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
setOnClickListener(new OnClickListener() {
|
setOnClickListener(v -> {
|
||||||
@Override
|
if (mListener != null && mBinding.isBound()) {
|
||||||
public void onClick(final View v) {
|
mListener.onPersonClicked(mBinding.getData());
|
||||||
if (mListener != null && mBinding.isBound()) {
|
|
||||||
mListener.onPersonClicked(mBinding.getData());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
final OnLongClickListener onLongClickListener = new OnLongClickListener() {
|
final OnLongClickListener onLongClickListener = v -> {
|
||||||
@Override
|
if (mListener != null && mBinding.isBound()) {
|
||||||
public boolean onLongClick(View v) {
|
return mListener.onPersonLongClicked(mBinding.getData());
|
||||||
if (mListener != null && mBinding.isBound()) {
|
|
||||||
return mListener.onPersonLongClicked(mBinding.getData());
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
};
|
};
|
||||||
setOnLongClickListener(onLongClickListener);
|
setOnLongClickListener(onLongClickListener);
|
||||||
mContactIconView.setOnLongClickListener(onLongClickListener);
|
mContactIconView.setOnLongClickListener(onLongClickListener);
|
||||||
|
|||||||
@@ -28,7 +28,6 @@ import android.content.res.Resources;
|
|||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.View.OnClickListener;
|
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.widget.ArrayAdapter;
|
import android.widget.ArrayAdapter;
|
||||||
import android.widget.ListView;
|
import android.widget.ListView;
|
||||||
@@ -108,12 +107,7 @@ public class SmsStorageLowWarningFragment extends Fragment {
|
|||||||
|
|
||||||
builder.setTitle(R.string.sms_storage_low_title)
|
builder.setTitle(R.string.sms_storage_low_title)
|
||||||
.setView(dialogLayout)
|
.setView(dialogLayout)
|
||||||
.setNegativeButton(R.string.ignore, new DialogInterface.OnClickListener() {
|
.setNegativeButton(R.string.ignore, (dialog, id) -> dialog.cancel());
|
||||||
@Override
|
|
||||||
public void onClick(DialogInterface dialog, int id) {
|
|
||||||
dialog.cancel();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
final Dialog dialog = builder.create();
|
final Dialog dialog = builder.create();
|
||||||
dialog.setCanceledOnTouchOutside(false);
|
dialog.setCanceledOnTouchOutside(false);
|
||||||
@@ -145,12 +139,9 @@ public class SmsStorageLowWarningFragment extends Fragment {
|
|||||||
|
|
||||||
final String action = getItem(position);
|
final String action = getItem(position);
|
||||||
actionItemView.setText(action);
|
actionItemView.setText(action);
|
||||||
actionItemView.setOnClickListener(new OnClickListener() {
|
actionItemView.setOnClickListener(view1 -> {
|
||||||
@Override
|
dismiss();
|
||||||
public void onClick(final View view) {
|
((SmsStorageLowWarningFragment) getTargetFragment()).confirm(position);
|
||||||
dismiss();
|
|
||||||
((SmsStorageLowWarningFragment) getTargetFragment()).confirm(position);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
return actionItemView;
|
return actionItemView;
|
||||||
}
|
}
|
||||||
@@ -191,25 +182,15 @@ public class SmsStorageLowWarningFragment extends Fragment {
|
|||||||
final AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
|
final AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
|
||||||
builder.setTitle(R.string.sms_storage_low_title)
|
builder.setTitle(R.string.sms_storage_low_title)
|
||||||
.setMessage(getConfirmDialogMessage(actionIndex))
|
.setMessage(getConfirmDialogMessage(actionIndex))
|
||||||
.setNegativeButton(android.R.string.cancel,
|
.setNegativeButton(android.R.string.cancel, (dialog, button) -> {
|
||||||
new DialogInterface.OnClickListener() {
|
dismiss();
|
||||||
@Override
|
((SmsStorageLowWarningFragment) getTargetFragment()).cancel();
|
||||||
public void onClick(final DialogInterface dialog,
|
|
||||||
final int button) {
|
|
||||||
dismiss();
|
|
||||||
((SmsStorageLowWarningFragment) getTargetFragment()).cancel();
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
.setPositiveButton(android.R.string.ok,
|
.setPositiveButton(android.R.string.ok, (dialog, button) -> {
|
||||||
new DialogInterface.OnClickListener() {
|
dismiss();
|
||||||
@Override
|
handleAction(actionIndex);
|
||||||
public void onClick(final DialogInterface dialog,
|
getActivity().finish();
|
||||||
final int button) {
|
SmsStorageStatusManager.cancelStorageLowNotification();
|
||||||
dismiss();
|
|
||||||
handleAction(actionIndex);
|
|
||||||
getActivity().finish();
|
|
||||||
SmsStorageStatusManager.cancelStorageLowNotification();
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
return builder.create();
|
return builder.create();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,7 +22,6 @@ import androidx.annotation.Nullable;
|
|||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.View.OnClickListener;
|
|
||||||
import android.view.ViewGroup.MarginLayoutParams;
|
import android.view.ViewGroup.MarginLayoutParams;
|
||||||
import android.widget.FrameLayout;
|
import android.widget.FrameLayout;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
@@ -292,13 +291,10 @@ public class SnackBar {
|
|||||||
} else {
|
} else {
|
||||||
mActionTextView.setVisibility(View.VISIBLE);
|
mActionTextView.setVisibility(View.VISIBLE);
|
||||||
mActionTextView.setText(mAction.getActionLabel());
|
mActionTextView.setText(mAction.getActionLabel());
|
||||||
mActionTextView.setOnClickListener(new OnClickListener() {
|
mActionTextView.setOnClickListener(v -> {
|
||||||
@Override
|
mAction.getActionRunnable().run();
|
||||||
public void onClick(final View v) {
|
if (mListener != null) {
|
||||||
mAction.getActionRunnable().run();
|
mListener.onActionClick();
|
||||||
if (mListener != null) {
|
|
||||||
mListener.onActionClick();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,7 +23,6 @@ import android.os.Handler;
|
|||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
import android.util.DisplayMetrics;
|
import android.util.DisplayMetrics;
|
||||||
import android.view.Gravity;
|
import android.view.Gravity;
|
||||||
import android.view.MotionEvent;
|
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.View.MeasureSpec;
|
import android.view.View.MeasureSpec;
|
||||||
import android.view.View.OnAttachStateChangeListener;
|
import android.view.View.OnAttachStateChangeListener;
|
||||||
@@ -34,7 +33,6 @@ import android.view.ViewPropertyAnimator;
|
|||||||
import android.view.ViewTreeObserver.OnGlobalLayoutListener;
|
import android.view.ViewTreeObserver.OnGlobalLayoutListener;
|
||||||
import android.view.WindowManager;
|
import android.view.WindowManager;
|
||||||
import android.widget.PopupWindow;
|
import android.widget.PopupWindow;
|
||||||
import android.widget.PopupWindow.OnDismissListener;
|
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
|
|
||||||
@@ -66,28 +64,15 @@ public class SnackBarManager {
|
|||||||
return sInstance;
|
return sInstance;
|
||||||
}
|
}
|
||||||
|
|
||||||
private final Runnable mDismissRunnable = new Runnable() {
|
private final Runnable mDismissRunnable = this::dismiss;
|
||||||
@Override
|
|
||||||
public void run() {
|
private final OnTouchListener mDismissOnTouchListener = (view, event) -> {
|
||||||
dismiss();
|
// Dismiss the {@link SnackBar} but don't consume the event.
|
||||||
}
|
dismiss();
|
||||||
|
return false;
|
||||||
};
|
};
|
||||||
|
|
||||||
private final OnTouchListener mDismissOnTouchListener = new OnTouchListener() {
|
private final SnackBarListener mDismissOnUserTapListener = this::dismiss;
|
||||||
@Override
|
|
||||||
public boolean onTouch(final View view, final MotionEvent event) {
|
|
||||||
// Dismiss the {@link SnackBar} but don't consume the event.
|
|
||||||
dismiss();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
private final SnackBarListener mDismissOnUserTapListener = new SnackBarListener() {
|
|
||||||
@Override
|
|
||||||
public void onActionClick() {
|
|
||||||
dismiss();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
private final OnAttachStateChangeListener mAttachStateChangeListener =
|
private final OnAttachStateChangeListener mAttachStateChangeListener =
|
||||||
new OnAttachStateChangeListener() {
|
new OnAttachStateChangeListener() {
|
||||||
@@ -184,20 +169,12 @@ public class SnackBarManager {
|
|||||||
// You'd expect PopupWindow.showAsDropDown to ensure the popup moves with the anchor
|
// You'd expect PopupWindow.showAsDropDown to ensure the popup moves with the anchor
|
||||||
// view, which it does for scrolling, but not layout changes, so we have to manually
|
// view, which it does for scrolling, but not layout changes, so we have to manually
|
||||||
// update while the snackbar is showing
|
// update while the snackbar is showing
|
||||||
final OnGlobalLayoutListener listener = new OnGlobalLayoutListener() {
|
final OnGlobalLayoutListener listener = () ->
|
||||||
@Override
|
|
||||||
public void onGlobalLayout() {
|
|
||||||
mPopupWindow.update(anchorView, 0, getRelativeOffset(snackBar),
|
mPopupWindow.update(anchorView, 0, getRelativeOffset(snackBar),
|
||||||
anchorView.getWidth(), LayoutParams.WRAP_CONTENT);
|
anchorView.getWidth(), LayoutParams.WRAP_CONTENT);
|
||||||
}
|
|
||||||
};
|
|
||||||
anchorView.getViewTreeObserver().addOnGlobalLayoutListener(listener);
|
anchorView.getViewTreeObserver().addOnGlobalLayoutListener(listener);
|
||||||
mPopupWindow.setOnDismissListener(new OnDismissListener() {
|
mPopupWindow.setOnDismissListener(() ->
|
||||||
@Override
|
anchorView.getViewTreeObserver().removeOnGlobalLayoutListener(listener));
|
||||||
public void onDismiss() {
|
|
||||||
anchorView.getViewTreeObserver().removeOnGlobalLayoutListener(listener);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
mPopupWindow.showAsDropDown(anchorView, 0, getRelativeOffset(snackBar));
|
mPopupWindow.showAsDropDown(anchorView, 0, getRelativeOffset(snackBar));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -205,23 +182,20 @@ public class SnackBarManager {
|
|||||||
|
|
||||||
// Animate the toast bar into view.
|
// Animate the toast bar into view.
|
||||||
placeSnackBarOffScreen(snackBar);
|
placeSnackBarOffScreen(snackBar);
|
||||||
animateSnackBarOnScreen(snackBar).withEndAction(new Runnable() {
|
animateSnackBarOnScreen(snackBar).withEndAction(() -> {
|
||||||
@Override
|
mCurrentSnackBar.setEnabled(true);
|
||||||
public void run() {
|
makeCurrentSnackBarDismissibleOnTouch();
|
||||||
mCurrentSnackBar.setEnabled(true);
|
// Fire an accessibility event as needed
|
||||||
makeCurrentSnackBarDismissibleOnTouch();
|
String snackBarText = snackBar.getMessageText();
|
||||||
// Fire an accessibility event as needed
|
if (!TextUtils.isEmpty(snackBarText) &&
|
||||||
String snackBarText = snackBar.getMessageText();
|
TextUtils.getTrimmedLength(snackBarText) > 0) {
|
||||||
if (!TextUtils.isEmpty(snackBarText) &&
|
snackBarText = snackBarText.trim();
|
||||||
TextUtils.getTrimmedLength(snackBarText) > 0) {
|
final String snackBarActionText = snackBar.getActionLabel();
|
||||||
snackBarText = snackBarText.trim();
|
if (!TextUtil.isAllWhitespace(snackBarActionText)) {
|
||||||
final String snackBarActionText = snackBar.getActionLabel();
|
snackBarText = Joiner.on(", ").join(snackBarText, snackBarActionText);
|
||||||
if (!TextUtil.isAllWhitespace(snackBarActionText)) {
|
|
||||||
snackBarText = Joiner.on(", ").join(snackBarText, snackBarActionText);
|
|
||||||
}
|
|
||||||
AccessibilityUtil.announceForAccessibilityCompat(snackBar.getSnackBarView(),
|
|
||||||
null /*accessibilityManager*/, snackBarText);
|
|
||||||
}
|
}
|
||||||
|
AccessibilityUtil.announceForAccessibilityCompat(snackBar.getSnackBarView(),
|
||||||
|
null /*accessibilityManager*/, snackBarText);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -249,28 +223,25 @@ public class SnackBarManager {
|
|||||||
|
|
||||||
// Animate the toast bar down.
|
// Animate the toast bar down.
|
||||||
final View rootView = snackBar.getRootView();
|
final View rootView = snackBar.getRootView();
|
||||||
animateSnackBarOffScreen(snackBar).withEndAction(new Runnable() {
|
animateSnackBarOffScreen(snackBar).withEndAction(() -> {
|
||||||
@Override
|
rootView.setVisibility(View.GONE);
|
||||||
public void run() {
|
try {
|
||||||
rootView.setVisibility(View.GONE);
|
mPopupWindow.dismiss();
|
||||||
try {
|
} catch (IllegalArgumentException e) {
|
||||||
mPopupWindow.dismiss();
|
// PopupWindow.dismiss() will fire an IllegalArgumentException if the activity
|
||||||
} catch (IllegalArgumentException e) {
|
// has already ended while we were animating
|
||||||
// PopupWindow.dismiss() will fire an IllegalArgumentException if the activity
|
}
|
||||||
// has already ended while we were animating
|
snackBar.getParentView()
|
||||||
}
|
.removeOnAttachStateChangeListener(mAttachStateChangeListener);
|
||||||
snackBar.getParentView()
|
|
||||||
.removeOnAttachStateChangeListener(mAttachStateChangeListener);
|
|
||||||
|
|
||||||
mCurrentSnackBar = null;
|
mCurrentSnackBar = null;
|
||||||
mIsCurrentlyDismissing = false;
|
mIsCurrentlyDismissing = false;
|
||||||
|
|
||||||
// Show the next toast if one is waiting.
|
// Show the next toast if one is waiting.
|
||||||
if (mNextSnackBar != null) {
|
if (mNextSnackBar != null) {
|
||||||
final SnackBar localNextSnackBar = mNextSnackBar;
|
final SnackBar localNextSnackBar = mNextSnackBar;
|
||||||
mNextSnackBar = null;
|
mNextSnackBar = null;
|
||||||
show(localNextSnackBar);
|
show(localNextSnackBar);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2015 The Android Open Source Project
|
* Copyright (C) 2015 The Android Open Source Project
|
||||||
|
* Copyright (C) 2024 The LineageOS Project
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -25,11 +26,9 @@ import android.view.Menu;
|
|||||||
import android.view.MenuInflater;
|
import android.view.MenuInflater;
|
||||||
import android.view.MenuItem;
|
import android.view.MenuItem;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.View.OnLayoutChangeListener;
|
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.widget.ExpandableListAdapter;
|
import android.widget.ExpandableListAdapter;
|
||||||
import android.widget.ExpandableListView;
|
import android.widget.ExpandableListView;
|
||||||
import android.widget.ExpandableListView.OnChildClickListener;
|
|
||||||
|
|
||||||
import com.android.messaging.R;
|
import com.android.messaging.R;
|
||||||
import com.android.messaging.datamodel.DataModel;
|
import com.android.messaging.datamodel.DataModel;
|
||||||
@@ -73,34 +72,27 @@ public class VCardDetailFragment extends Fragment implements PersonItemDataListe
|
|||||||
Assert.notNull(mVCardUri);
|
Assert.notNull(mVCardUri);
|
||||||
final View view = inflater.inflate(R.layout.vcard_detail_fragment, container, false);
|
final View view = inflater.inflate(R.layout.vcard_detail_fragment, container, false);
|
||||||
mListView = (ExpandableListView) view.findViewById(R.id.list);
|
mListView = (ExpandableListView) view.findViewById(R.id.list);
|
||||||
mListView.addOnLayoutChangeListener(new OnLayoutChangeListener() {
|
mListView.addOnLayoutChangeListener((v, left, top, right, bottom, oldLeft, oldTop, oldRight,
|
||||||
@Override
|
oldBottom) -> {
|
||||||
public void onLayoutChange(final View v, final int left, final int top, final int right,
|
mListView.setIndicatorBounds(mListView.getWidth() - getResources().
|
||||||
final int bottom, final int oldLeft, final int oldTop, final int oldRight,
|
getDimensionPixelSize(R.dimen.vcard_detail_group_indicator_width),
|
||||||
final int oldBottom) {
|
mListView.getWidth());
|
||||||
mListView.setIndicatorBounds(mListView.getWidth() - getResources()
|
|
||||||
.getDimensionPixelSize(R.dimen.vcard_detail_group_indicator_width),
|
|
||||||
mListView.getWidth());
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
mListView.setOnChildClickListener(new OnChildClickListener() {
|
mListView.setOnChildClickListener((expandableListView, clickedView, groupPosition,
|
||||||
@Override
|
childPosition, childId) -> {
|
||||||
public boolean onChildClick(ExpandableListView expandableListView, View clickedView,
|
if (!(clickedView instanceof PersonItemView)) {
|
||||||
int groupPosition, int childPosition, long childId) {
|
|
||||||
if (!(clickedView instanceof PersonItemView)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
final Intent intent = ((PersonItemView) clickedView).getClickIntent();
|
|
||||||
if (intent != null) {
|
|
||||||
try {
|
|
||||||
startActivity(intent);
|
|
||||||
} catch (ActivityNotFoundException e) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
final Intent intent = ((PersonItemView) clickedView).getClickIntent();
|
||||||
|
if (intent != null) {
|
||||||
|
try {
|
||||||
|
startActivity(intent);
|
||||||
|
} catch (ActivityNotFoundException e) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
});
|
});
|
||||||
mBinding.bind(DataModel.get().createVCardContactItemData(getActivity(), mVCardUri));
|
mBinding.bind(DataModel.get().createVCardContactItemData(getActivity(), mVCardUri));
|
||||||
mBinding.getData().setListener(this);
|
mBinding.getData().setListener(this);
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2015 The Android Open Source Project
|
* Copyright (C) 2015 The Android Open Source Project
|
||||||
|
* Copyright (C) 2024 The LineageOS Project
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -95,15 +96,12 @@ public class VideoThumbnailView extends FrameLayout {
|
|||||||
mVideoView.clearFocus();
|
mVideoView.clearFocus();
|
||||||
addView(mVideoView, 0, new ViewGroup.LayoutParams(
|
addView(mVideoView, 0, new ViewGroup.LayoutParams(
|
||||||
ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
|
ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
|
||||||
mVideoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
|
mVideoView.setOnPreparedListener(mediaPlayer -> {
|
||||||
@Override
|
mVideoLoaded = true;
|
||||||
public void onPrepared(final MediaPlayer mediaPlayer) {
|
mVideoWidth = mediaPlayer.getVideoWidth();
|
||||||
mVideoLoaded = true;
|
mVideoHeight = mediaPlayer.getVideoHeight();
|
||||||
mVideoWidth = mediaPlayer.getVideoWidth();
|
mediaPlayer.setLooping(loop);
|
||||||
mVideoHeight = mediaPlayer.getVideoHeight();
|
trySwitchToVideo();
|
||||||
mediaPlayer.setLooping(loop);
|
|
||||||
trySwitchToVideo();
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
mVideoView.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
|
mVideoView.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
|
||||||
@Override
|
@Override
|
||||||
@@ -111,12 +109,7 @@ public class VideoThumbnailView extends FrameLayout {
|
|||||||
mPlayButton.setVisibility(View.VISIBLE);
|
mPlayButton.setVisibility(View.VISIBLE);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
mVideoView.setOnErrorListener(new MediaPlayer.OnErrorListener() {
|
mVideoView.setOnErrorListener((mediaPlayer, i, i2) -> true);
|
||||||
@Override
|
|
||||||
public boolean onError(final MediaPlayer mediaPlayer, final int i, final int i2) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} else {
|
} else {
|
||||||
mVideoView = null;
|
mVideoView = null;
|
||||||
}
|
}
|
||||||
@@ -125,28 +118,22 @@ public class VideoThumbnailView extends FrameLayout {
|
|||||||
if (loop) {
|
if (loop) {
|
||||||
mPlayButton.setVisibility(View.GONE);
|
mPlayButton.setVisibility(View.GONE);
|
||||||
} else {
|
} else {
|
||||||
mPlayButton.setOnClickListener(new OnClickListener() {
|
mPlayButton.setOnClickListener(view -> {
|
||||||
@Override
|
if (mVideoSource == null) {
|
||||||
public void onClick(final View view) {
|
return;
|
||||||
if (mVideoSource == null) {
|
}
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mMode == MODE_PLAYABLE_VIDEO) {
|
if (mMode == MODE_PLAYABLE_VIDEO) {
|
||||||
mVideoView.seekTo(0);
|
mVideoView.seekTo(0);
|
||||||
start();
|
start();
|
||||||
} else {
|
} else {
|
||||||
UIIntents.get().launchFullScreenVideoViewer(getContext(), mVideoSource);
|
UIIntents.get().launchFullScreenVideoViewer(getContext(), mVideoSource);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
mPlayButton.setOnLongClickListener(new OnLongClickListener() {
|
mPlayButton.setOnLongClickListener(view -> {
|
||||||
@Override
|
// Button prevents long click from propagating up, do it manually
|
||||||
public boolean onLongClick(final View view) {
|
VideoThumbnailView.this.performLongClick();
|
||||||
// Button prevents long click from propagating up, do it manually
|
return true;
|
||||||
VideoThumbnailView.this.performLongClick();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -157,12 +157,7 @@ public class ViewPagerTabs extends HorizontalScrollView implements ViewPager.OnP
|
|||||||
textView.setText(tabTitle);
|
textView.setText(tabTitle);
|
||||||
textView.setBackgroundResource(R.drawable.contact_picker_tab_background_selector);
|
textView.setBackgroundResource(R.drawable.contact_picker_tab_background_selector);
|
||||||
textView.setGravity(Gravity.CENTER);
|
textView.setGravity(Gravity.CENTER);
|
||||||
textView.setOnClickListener(new OnClickListener() {
|
textView.setOnClickListener(v -> mPager.setCurrentItem(getRtlPosition(position)));
|
||||||
@Override
|
|
||||||
public void onClick(View v) {
|
|
||||||
mPager.setCurrentItem(getRtlPosition(position));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Assign various text appearance related attributes to child views.
|
// Assign various text appearance related attributes to child views.
|
||||||
if (mTextStyle > 0) {
|
if (mTextStyle > 0) {
|
||||||
|
|||||||
@@ -112,12 +112,8 @@ public class PopupTransitionAnimation extends Animation {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private final StringBuilder mEvents = new StringBuilder();
|
private final StringBuilder mEvents = new StringBuilder();
|
||||||
private final Runnable mCleanupRunnable = new Runnable() {
|
private final Runnable mCleanupRunnable = () ->
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
LogUtil.w(LogUtil.BUGLE_TAG, "PopupTransitionAnimation: " + mEvents);
|
LogUtil.w(LogUtil.BUGLE_TAG, "PopupTransitionAnimation: " + mEvents);
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Ensures the animation is ready before starting the animation.
|
* Ensures the animation is ready before starting the animation.
|
||||||
@@ -210,17 +206,14 @@ public class PopupTransitionAnimation extends Animation {
|
|||||||
mViewToAnimate.setVisibility(View.VISIBLE);
|
mViewToAnimate.setVisibility(View.VISIBLE);
|
||||||
// Delay dismissing the popup window to let mViewToAnimate draw under it and reduce the
|
// Delay dismissing the popup window to let mViewToAnimate draw under it and reduce the
|
||||||
// flash
|
// flash
|
||||||
ThreadUtil.getMainThreadHandler().post(new Runnable() {
|
ThreadUtil.getMainThreadHandler().post(() -> {
|
||||||
@Override
|
try {
|
||||||
public void run() {
|
mPopupWindow.dismiss();
|
||||||
try {
|
} catch (IllegalArgumentException e) {
|
||||||
mPopupWindow.dismiss();
|
// PopupWindow.dismiss() will fire an IllegalArgumentException if the activity
|
||||||
} catch (IllegalArgumentException e) {
|
// has already ended while we were animating
|
||||||
// PopupWindow.dismiss() will fire an IllegalArgumentException if the activity
|
|
||||||
// has already ended while we were animating
|
|
||||||
}
|
|
||||||
ThreadUtil.getMainThreadHandler().removeCallbacks(mCleanupRunnable);
|
|
||||||
}
|
}
|
||||||
|
ThreadUtil.getMainThreadHandler().removeCallbacks(mCleanupRunnable);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2015 The Android Open Source Project
|
* Copyright (C) 2015 The Android Open Source Project
|
||||||
|
* Copyright (C) 2024 The LineageOS Project
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -168,17 +169,14 @@ public class ViewGroupItemVerticalExplodeAnimation {
|
|||||||
expandLayer.animate().scaleY(scale)
|
expandLayer.animate().scaleY(scale)
|
||||||
.setDuration(mDuration)
|
.setDuration(mDuration)
|
||||||
.setInterpolator(UiUtils.EASE_IN_INTERPOLATOR)
|
.setInterpolator(UiUtils.EASE_IN_INTERPOLATOR)
|
||||||
.withEndAction(new Runnable() {
|
.withEndAction(() -> {
|
||||||
@Override
|
// Clean up the views added to overlay on animation finish.
|
||||||
public void run() {
|
overlay.remove(shadowContainerLayer);
|
||||||
// Clean up the views added to overlay on animation finish.
|
mViewToAnimate.setBackground(oldBackground);
|
||||||
overlay.remove(shadowContainerLayer);
|
if (mViewBitmap != null) {
|
||||||
mViewToAnimate.setBackground(oldBackground);
|
mViewBitmap.recycle();
|
||||||
if (mViewBitmap != null) {
|
|
||||||
mViewBitmap.recycle();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2015 The Android Open Source Project
|
* Copyright (C) 2015 The Android Open Source Project
|
||||||
|
* Copyright (C) 2024 The LineageOS Project
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -19,7 +20,6 @@ import android.app.AlertDialog;
|
|||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.View.OnClickListener;
|
|
||||||
import android.widget.RadioButton;
|
import android.widget.RadioButton;
|
||||||
|
|
||||||
import com.android.messaging.R;
|
import com.android.messaging.R;
|
||||||
@@ -70,18 +70,8 @@ public class GroupMmsSettingDialog {
|
|||||||
rootView.findViewById(R.id.disable_group_mms_button);
|
rootView.findViewById(R.id.disable_group_mms_button);
|
||||||
final RadioButton enableButton = (RadioButton)
|
final RadioButton enableButton = (RadioButton)
|
||||||
rootView.findViewById(R.id.enable_group_mms_button);
|
rootView.findViewById(R.id.enable_group_mms_button);
|
||||||
disableButton.setOnClickListener(new OnClickListener() {
|
disableButton.setOnClickListener(view -> changeGroupMmsSettings(false));
|
||||||
@Override
|
enableButton.setOnClickListener(view -> changeGroupMmsSettings(true));
|
||||||
public void onClick(View view) {
|
|
||||||
changeGroupMmsSettings(false);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
enableButton.setOnClickListener(new OnClickListener() {
|
|
||||||
@Override
|
|
||||||
public void onClick(View view) {
|
|
||||||
changeGroupMmsSettings(true);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
final boolean mmsEnabled = BuglePrefs.getSubscriptionPrefs(mSubId).getBoolean(
|
final boolean mmsEnabled = BuglePrefs.getSubscriptionPrefs(mSubId).getBoolean(
|
||||||
mContext.getString(R.string.group_mms_pref_key),
|
mContext.getString(R.string.group_mms_pref_key),
|
||||||
mContext.getResources().getBoolean(R.bool.group_mms_pref_default));
|
mContext.getResources().getBoolean(R.bool.group_mms_pref_default));
|
||||||
|
|||||||
@@ -125,12 +125,9 @@ public class PerSubscriptionSettingsActivity extends BugleActionBarActivity {
|
|||||||
// is being sent, making sure we will have a self number for group mms.
|
// is being sent, making sure we will have a self number for group mms.
|
||||||
mmsCategory.removePreference(mGroupMmsPreference);
|
mmsCategory.removePreference(mGroupMmsPreference);
|
||||||
} else {
|
} else {
|
||||||
mGroupMmsPreference.setOnPreferenceClickListener(new OnPreferenceClickListener() {
|
mGroupMmsPreference.setOnPreferenceClickListener(pref -> {
|
||||||
@Override
|
GroupMmsSettingDialog.showDialog(getActivity(), mSubId);
|
||||||
public boolean onPreferenceClick(Preference pref) {
|
return true;
|
||||||
GroupMmsSettingDialog.showDialog(getActivity(), mSubId);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
updateGroupMmsPrefSummary();
|
updateGroupMmsPrefSummary();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,7 +27,6 @@ import android.text.TextUtils;
|
|||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.MenuItem;
|
import android.view.MenuItem;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.View.OnClickListener;
|
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.widget.ArrayAdapter;
|
import android.widget.ArrayAdapter;
|
||||||
import android.widget.ListView;
|
import android.widget.ListView;
|
||||||
@@ -155,24 +154,21 @@ public class SettingsActivity extends BugleActionBarActivity {
|
|||||||
} else {
|
} else {
|
||||||
subtitleTextView.setVisibility(View.GONE);
|
subtitleTextView.setVisibility(View.GONE);
|
||||||
}
|
}
|
||||||
itemView.setOnClickListener(new OnClickListener() {
|
itemView.setOnClickListener(view -> {
|
||||||
@Override
|
switch (item.getType()) {
|
||||||
public void onClick(View view) {
|
case SettingsItem.TYPE_GENERAL_SETTINGS:
|
||||||
switch (item.getType()) {
|
UIIntents.get().launchApplicationSettingsActivity(getActivity(),
|
||||||
case SettingsItem.TYPE_GENERAL_SETTINGS:
|
false /* topLevel */);
|
||||||
UIIntents.get().launchApplicationSettingsActivity(getActivity(),
|
break;
|
||||||
false /* topLevel */);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SettingsItem.TYPE_PER_SUBSCRIPTION_SETTINGS:
|
case SettingsItem.TYPE_PER_SUBSCRIPTION_SETTINGS:
|
||||||
UIIntents.get().launchPerSubscriptionSettingsActivity(getActivity(),
|
UIIntents.get().launchPerSubscriptionSettingsActivity(getActivity(),
|
||||||
item.getSubId(), item.getActivityTitle());
|
item.getSubId(), item.getActivityTitle());
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
Assert.fail("unrecognized setting type!");
|
Assert.fail("unrecognized setting type!");
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return itemView;
|
return itemView;
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2015 The Android Open Source Project
|
* Copyright (C) 2015 The Android Open Source Project
|
||||||
|
* Copyright (C) 2024 The LineageOS Project
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -55,30 +56,19 @@ public class AttachmentGridItemView extends FrameLayout {
|
|||||||
super.onFinishInflate();
|
super.onFinishInflate();
|
||||||
mAttachmentViewContainer = (FrameLayout) findViewById(R.id.attachment_container);
|
mAttachmentViewContainer = (FrameLayout) findViewById(R.id.attachment_container);
|
||||||
mCheckBox = (CheckBox) findViewById(R.id.checkbox);
|
mCheckBox = (CheckBox) findViewById(R.id.checkbox);
|
||||||
mCheckBox.setOnClickListener(new OnClickListener() {
|
mCheckBox.setOnClickListener(v -> mHostInterface.onItemCheckedChanged(
|
||||||
@Override
|
AttachmentGridItemView.this, mAttachmentData));
|
||||||
public void onClick(final View v) {
|
setOnClickListener(v -> mHostInterface.onItemClicked(AttachmentGridItemView.this,
|
||||||
mHostInterface.onItemCheckedChanged(AttachmentGridItemView.this, mAttachmentData);
|
mAttachmentData));
|
||||||
}
|
addOnLayoutChangeListener((v, left, top, right, bottom, oldLeft, oldTop, oldRight,
|
||||||
});
|
oldBottom) -> {
|
||||||
setOnClickListener(new OnClickListener() {
|
// Enlarge the clickable region for the checkbox.
|
||||||
@Override
|
final int touchAreaIncrease = getResources().getDimensionPixelOffset(
|
||||||
public void onClick(final View v) {
|
R.dimen.attachment_grid_checkbox_area_increase);
|
||||||
mHostInterface.onItemClicked(AttachmentGridItemView.this, mAttachmentData);
|
final Rect region = new Rect();
|
||||||
}
|
mCheckBox.getHitRect(region);
|
||||||
});
|
region.inset(-touchAreaIncrease, -touchAreaIncrease);
|
||||||
addOnLayoutChangeListener(new OnLayoutChangeListener() {
|
setTouchDelegate(new TouchDelegate(region, mCheckBox));
|
||||||
@Override
|
|
||||||
public void onLayoutChange(View v, int left, int top, int right, int bottom,
|
|
||||||
int oldLeft, int oldTop, int oldRight, int oldBottom) {
|
|
||||||
// Enlarge the clickable region for the checkbox.
|
|
||||||
final int touchAreaIncrease = getResources().getDimensionPixelOffset(
|
|
||||||
R.dimen.attachment_grid_checkbox_area_increase);
|
|
||||||
final Rect region = new Rect();
|
|
||||||
mCheckBox.getHitRect(region);
|
|
||||||
region.inset(-touchAreaIncrease, -touchAreaIncrease);
|
|
||||||
setTouchDelegate(new TouchDelegate(region, mCheckBox));
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2015 The Android Open Source Project
|
* Copyright (C) 2015 The Android Open Source Project
|
||||||
|
* Copyright (C) 2024 The LineageOS Project
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -36,7 +37,6 @@ import android.view.LayoutInflater;
|
|||||||
import android.view.Menu;
|
import android.view.Menu;
|
||||||
import android.view.MenuItem;
|
import android.view.MenuItem;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.View.OnClickListener;
|
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
|
|
||||||
import com.android.messaging.R;
|
import com.android.messaging.R;
|
||||||
@@ -182,12 +182,7 @@ public class ContactPickerFragment extends Fragment implements ContactPickerData
|
|||||||
mToolbar = (Toolbar) view.findViewById(R.id.toolbar);
|
mToolbar = (Toolbar) view.findViewById(R.id.toolbar);
|
||||||
mToolbar.setNavigationIcon(R.drawable.ic_arrow_back_light);
|
mToolbar.setNavigationIcon(R.drawable.ic_arrow_back_light);
|
||||||
mToolbar.setNavigationContentDescription(R.string.back);
|
mToolbar.setNavigationContentDescription(R.string.back);
|
||||||
mToolbar.setNavigationOnClickListener(new OnClickListener() {
|
mToolbar.setNavigationOnClickListener(v -> mHost.onBackButtonPressed());
|
||||||
@Override
|
|
||||||
public void onClick(final View v) {
|
|
||||||
mHost.onBackButtonPressed();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
mToolbar.inflateMenu(R.menu.compose_menu);
|
mToolbar.inflateMenu(R.menu.compose_menu);
|
||||||
mToolbar.setOnMenuItemClickListener(this);
|
mToolbar.setOnMenuItemClickListener(this);
|
||||||
@@ -325,13 +320,10 @@ public class ContactPickerFragment extends Fragment implements ContactPickerData
|
|||||||
|
|
||||||
// showImeKeyboard() won't work until the layout is ready, so wait until layout is complete
|
// showImeKeyboard() won't work until the layout is ready, so wait until layout is complete
|
||||||
// before showing the soft keyboard.
|
// before showing the soft keyboard.
|
||||||
UiUtils.doOnceAfterLayoutChange(mRootView, new Runnable() {
|
UiUtils.doOnceAfterLayoutChange(mRootView, () -> {
|
||||||
@Override
|
final Activity activity = getActivity();
|
||||||
public void run() {
|
if (activity != null) {
|
||||||
final Activity activity = getActivity();
|
ImeUtil.get().showImeKeyboard(activity, mRecipientTextView);
|
||||||
if (activity != null) {
|
|
||||||
ImeUtil.get().showImeKeyboard(activity, mRecipientTextView);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
mRecipientTextView.invalidate();
|
mRecipientTextView.invalidate();
|
||||||
@@ -541,19 +533,13 @@ public class ContactPickerFragment extends Fragment implements ContactPickerData
|
|||||||
|
|
||||||
mCustomHeaderViewPager.animate().alpha(show ? 1F : 0F)
|
mCustomHeaderViewPager.animate().alpha(show ? 1F : 0F)
|
||||||
.setStartDelay(!show ? UiUtils.COMPOSE_TRANSITION_DURATION : 0)
|
.setStartDelay(!show ? UiUtils.COMPOSE_TRANSITION_DURATION : 0)
|
||||||
.withStartAction(new Runnable() {
|
.withStartAction(() -> {
|
||||||
@Override
|
mCustomHeaderViewPager.setVisibility(View.VISIBLE);
|
||||||
public void run() {
|
mCustomHeaderViewPager.setAlpha(show ? 0F : 1F);
|
||||||
mCustomHeaderViewPager.setVisibility(View.VISIBLE);
|
|
||||||
mCustomHeaderViewPager.setAlpha(show ? 0F : 1F);
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
.withEndAction(new Runnable() {
|
.withEndAction(() -> {
|
||||||
@Override
|
mCustomHeaderViewPager.setVisibility(show ? View.VISIBLE : View.GONE);
|
||||||
public void run() {
|
mCustomHeaderViewPager.setAlpha(1F);
|
||||||
mCustomHeaderViewPager.setVisibility(show ? View.VISIBLE : View.GONE);
|
|
||||||
mCustomHeaderViewPager.setAlpha(1F);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2015 The Android Open Source Project
|
* Copyright (C) 2015 The Android Open Source Project
|
||||||
|
* Copyright (C) 2024 The LineageOS Project
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -59,38 +60,35 @@ public class ContactRecipientPhotoManager implements PhotoManager {
|
|||||||
public void populatePhotoBytesAsync(final RecipientEntry entry,
|
public void populatePhotoBytesAsync(final RecipientEntry entry,
|
||||||
final PhotoManagerCallback callback) {
|
final PhotoManagerCallback callback) {
|
||||||
// Post all media resource request to the main thread.
|
// Post all media resource request to the main thread.
|
||||||
ThreadUtil.getMainThreadHandler().post(new Runnable() {
|
ThreadUtil.getMainThreadHandler().post(() -> {
|
||||||
@Override
|
final Uri avatarUri = AvatarUriUtil.createAvatarUri(
|
||||||
public void run() {
|
ParticipantData.getFromRecipientEntry(entry));
|
||||||
final Uri avatarUri = AvatarUriUtil.createAvatarUri(
|
final AvatarRequestDescriptor descriptor =
|
||||||
ParticipantData.getFromRecipientEntry(entry));
|
new AvatarRequestDescriptor(avatarUri, mIconSize, mIconSize);
|
||||||
final AvatarRequestDescriptor descriptor =
|
final BindableMediaRequest<ImageResource> req = descriptor.buildAsyncMediaRequest(
|
||||||
new AvatarRequestDescriptor(avatarUri, mIconSize, mIconSize);
|
mContext,
|
||||||
final BindableMediaRequest<ImageResource> req = descriptor.buildAsyncMediaRequest(
|
new MediaResourceLoadListener<ImageResource>() {
|
||||||
mContext,
|
@Override
|
||||||
new MediaResourceLoadListener<ImageResource>() {
|
public void onMediaResourceLoaded(final MediaRequest<ImageResource> request,
|
||||||
@Override
|
final ImageResource resource, final boolean isCached) {
|
||||||
public void onMediaResourceLoaded(final MediaRequest<ImageResource> request,
|
entry.setPhotoBytes(resource.getBytes());
|
||||||
final ImageResource resource, final boolean isCached) {
|
callback.onPhotoBytesAsynchronouslyPopulated();
|
||||||
entry.setPhotoBytes(resource.getBytes());
|
}
|
||||||
callback.onPhotoBytesAsynchronouslyPopulated();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onMediaResourceLoadError(final MediaRequest<ImageResource> request,
|
public void onMediaResourceLoadError(final MediaRequest<ImageResource> request,
|
||||||
final Exception exception) {
|
final Exception exception) {
|
||||||
LogUtil.e(LogUtil.BUGLE_TAG, "Photo bytes loading failed due to " +
|
LogUtil.e(LogUtil.BUGLE_TAG, "Photo bytes loading failed due to " +
|
||||||
exception + " request key=" + request.getKey());
|
exception + " request key=" + request.getKey());
|
||||||
|
|
||||||
// Fall back to the default avatar image.
|
// Fall back to the default avatar image.
|
||||||
callback.onPhotoBytesAsyncLoadFailed();
|
callback.onPhotoBytesAsyncLoadFailed();
|
||||||
}});
|
}});
|
||||||
|
|
||||||
// Statically bind the request since it's not bound to any specific piece of UI.
|
// Statically bind the request since it's not bound to any specific piece of UI.
|
||||||
req.bind(IMAGE_BYTES_REQUEST_STATIC_BINDING_ID);
|
req.bind(IMAGE_BYTES_REQUEST_STATIC_BINDING_ID);
|
||||||
|
|
||||||
Factory.get().getMediaResourceManager().requestMediaResourceAsync(req);
|
Factory.get().getMediaResourceManager().requestMediaResourceAsync(req);
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -51,7 +51,6 @@ import com.android.messaging.datamodel.data.ConversationData.ConversationDataLis
|
|||||||
import com.android.messaging.datamodel.data.ConversationData.SimpleConversationDataListener;
|
import com.android.messaging.datamodel.data.ConversationData.SimpleConversationDataListener;
|
||||||
import com.android.messaging.datamodel.data.DraftMessageData;
|
import com.android.messaging.datamodel.data.DraftMessageData;
|
||||||
import com.android.messaging.datamodel.data.DraftMessageData.CheckDraftForSendTask;
|
import com.android.messaging.datamodel.data.DraftMessageData.CheckDraftForSendTask;
|
||||||
import com.android.messaging.datamodel.data.DraftMessageData.CheckDraftTaskCallback;
|
|
||||||
import com.android.messaging.datamodel.data.DraftMessageData.DraftMessageDataListener;
|
import com.android.messaging.datamodel.data.DraftMessageData.DraftMessageDataListener;
|
||||||
import com.android.messaging.datamodel.data.MessageData;
|
import com.android.messaging.datamodel.data.MessageData;
|
||||||
import com.android.messaging.datamodel.data.MessagePartData;
|
import com.android.messaging.datamodel.data.MessagePartData;
|
||||||
@@ -197,20 +196,14 @@ public class ComposeMessageView extends LinearLayout
|
|||||||
R.id.compose_message_text);
|
R.id.compose_message_text);
|
||||||
mComposeEditText.setOnEditorActionListener(this);
|
mComposeEditText.setOnEditorActionListener(this);
|
||||||
mComposeEditText.addTextChangedListener(this);
|
mComposeEditText.addTextChangedListener(this);
|
||||||
mComposeEditText.setOnFocusChangeListener(new OnFocusChangeListener() {
|
mComposeEditText.setOnFocusChangeListener((v, hasFocus) -> {
|
||||||
@Override
|
if (v == mComposeEditText && hasFocus) {
|
||||||
public void onFocusChange(final View v, final boolean hasFocus) {
|
mHost.onComposeEditTextFocused();
|
||||||
if (v == mComposeEditText && hasFocus) {
|
|
||||||
mHost.onComposeEditTextFocused();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
mComposeEditText.setOnClickListener(new View.OnClickListener() {
|
mComposeEditText.setOnClickListener(arg0 -> {
|
||||||
@Override
|
if (mHost.shouldHideAttachmentsWhenSimSelectorShown()) {
|
||||||
public void onClick(View arg0) {
|
hideSimSelector();
|
||||||
if (mHost.shouldHideAttachmentsWhenSimSelectorShown()) {
|
|
||||||
hideSimSelector();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -221,26 +214,20 @@ public class ComposeMessageView extends LinearLayout
|
|||||||
.getMaxTextLimit()) });
|
.getMaxTextLimit()) });
|
||||||
|
|
||||||
mSelfSendIcon = (SimIconView) findViewById(R.id.self_send_icon);
|
mSelfSendIcon = (SimIconView) findViewById(R.id.self_send_icon);
|
||||||
mSelfSendIcon.setOnClickListener(new OnClickListener() {
|
mSelfSendIcon.setOnClickListener(v -> {
|
||||||
@Override
|
boolean shown = mInputManager.toggleSimSelector(true /* animate */,
|
||||||
public void onClick(View v) {
|
getSelfSubscriptionListEntry());
|
||||||
|
hideAttachmentsWhenShowingSims(shown);
|
||||||
|
});
|
||||||
|
mSelfSendIcon.setOnLongClickListener(v -> {
|
||||||
|
if (mHost.shouldShowSubjectEditor()) {
|
||||||
|
showSubjectEditor();
|
||||||
|
} else {
|
||||||
boolean shown = mInputManager.toggleSimSelector(true /* animate */,
|
boolean shown = mInputManager.toggleSimSelector(true /* animate */,
|
||||||
getSelfSubscriptionListEntry());
|
getSelfSubscriptionListEntry());
|
||||||
hideAttachmentsWhenShowingSims(shown);
|
hideAttachmentsWhenShowingSims(shown);
|
||||||
}
|
}
|
||||||
});
|
return true;
|
||||||
mSelfSendIcon.setOnLongClickListener(new OnLongClickListener() {
|
|
||||||
@Override
|
|
||||||
public boolean onLongClick(final View v) {
|
|
||||||
if (mHost.shouldShowSubjectEditor()) {
|
|
||||||
showSubjectEditor();
|
|
||||||
} else {
|
|
||||||
boolean shown = mInputManager.toggleSimSelector(true /* animate */,
|
|
||||||
getSelfSubscriptionListEntry());
|
|
||||||
hideAttachmentsWhenShowingSims(shown);
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
mComposeSubjectText = (PlainTextEditText) findViewById(
|
mComposeSubjectText = (PlainTextEditText) findViewById(
|
||||||
@@ -255,35 +242,25 @@ public class ComposeMessageView extends LinearLayout
|
|||||||
.getMaxSubjectLength())});
|
.getMaxSubjectLength())});
|
||||||
|
|
||||||
mDeleteSubjectButton = (ImageButton) findViewById(R.id.delete_subject_button);
|
mDeleteSubjectButton = (ImageButton) findViewById(R.id.delete_subject_button);
|
||||||
mDeleteSubjectButton.setOnClickListener(new OnClickListener() {
|
mDeleteSubjectButton.setOnClickListener(clickView -> {
|
||||||
@Override
|
hideSubjectEditor();
|
||||||
public void onClick(final View clickView) {
|
mComposeSubjectText.setText(null);
|
||||||
hideSubjectEditor();
|
mBinding.getData().setMessageSubject(null);
|
||||||
mComposeSubjectText.setText(null);
|
|
||||||
mBinding.getData().setMessageSubject(null);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
mSubjectView = findViewById(R.id.subject_view);
|
mSubjectView = findViewById(R.id.subject_view);
|
||||||
|
|
||||||
mSendButton = (ImageButton) findViewById(R.id.send_message_button);
|
mSendButton = (ImageButton) findViewById(R.id.send_message_button);
|
||||||
mSendButton.setOnClickListener(new OnClickListener() {
|
mSendButton.setOnClickListener(clickView ->
|
||||||
@Override
|
sendMessageInternal(true /* checkMessageSize */));
|
||||||
public void onClick(final View clickView) {
|
mSendButton.setOnLongClickListener(arg0 -> {
|
||||||
sendMessageInternal(true /* checkMessageSize */);
|
boolean shown = mInputManager.toggleSimSelector(true /* animate */,
|
||||||
}
|
getSelfSubscriptionListEntry());
|
||||||
});
|
hideAttachmentsWhenShowingSims(shown);
|
||||||
mSendButton.setOnLongClickListener(new OnLongClickListener() {
|
if (mHost.shouldShowSubjectEditor()) {
|
||||||
@Override
|
showSubjectEditor();
|
||||||
public boolean onLongClick(final View arg0) {
|
|
||||||
boolean shown = mInputManager.toggleSimSelector(true /* animate */,
|
|
||||||
getSelfSubscriptionListEntry());
|
|
||||||
hideAttachmentsWhenShowingSims(shown);
|
|
||||||
if (mHost.shouldShowSubjectEditor()) {
|
|
||||||
showSubjectEditor();
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
});
|
});
|
||||||
mSendButton.setAccessibilityDelegate(new AccessibilityDelegate() {
|
mSendButton.setAccessibilityDelegate(new AccessibilityDelegate() {
|
||||||
@Override
|
@Override
|
||||||
@@ -306,12 +283,9 @@ public class ComposeMessageView extends LinearLayout
|
|||||||
|
|
||||||
mAttachMediaButton =
|
mAttachMediaButton =
|
||||||
(ImageButton) findViewById(R.id.attach_media_button);
|
(ImageButton) findViewById(R.id.attach_media_button);
|
||||||
mAttachMediaButton.setOnClickListener(new View.OnClickListener() {
|
mAttachMediaButton.setOnClickListener(clickView -> {
|
||||||
@Override
|
// Showing the media picker is treated as starting to compose the message.
|
||||||
public void onClick(final View clickView) {
|
mInputManager.showHideMediaPicker(true /* show */, true /* animate */);
|
||||||
// Showing the media picker is treated as starting to compose the message.
|
|
||||||
mInputManager.showHideMediaPicker(true /* show */, true /* animate */);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
mAttachmentPreview = (AttachmentPreview) findViewById(R.id.attachment_draft_view);
|
mAttachmentPreview = (AttachmentPreview) findViewById(R.id.attachment_draft_view);
|
||||||
@@ -394,69 +368,60 @@ public class ComposeMessageView extends LinearLayout
|
|||||||
mBinding.getData().setMessageSubject(subject);
|
mBinding.getData().setMessageSubject(subject);
|
||||||
// Asynchronously check the draft against various requirements before sending.
|
// Asynchronously check the draft against various requirements before sending.
|
||||||
mBinding.getData().checkDraftForAction(checkMessageSize,
|
mBinding.getData().checkDraftForAction(checkMessageSize,
|
||||||
mHost.getConversationSelfSubId(), new CheckDraftTaskCallback() {
|
mHost.getConversationSelfSubId(), (data, result) -> {
|
||||||
@Override
|
mBinding.ensureBound(data);
|
||||||
public void onDraftChecked(DraftMessageData data, int result) {
|
switch (result) {
|
||||||
mBinding.ensureBound(data);
|
case CheckDraftForSendTask.RESULT_PASSED:
|
||||||
switch (result) {
|
// Continue sending after check succeeded.
|
||||||
case CheckDraftForSendTask.RESULT_PASSED:
|
final MessageData message = mBinding.getData()
|
||||||
// Continue sending after check succeeded.
|
.prepareMessageForSending(mBinding);
|
||||||
final MessageData message = mBinding.getData()
|
if (message != null && message.hasContent()) {
|
||||||
.prepareMessageForSending(mBinding);
|
playSentSound();
|
||||||
if (message != null && message.hasContent()) {
|
mHost.sendMessage(message);
|
||||||
playSentSound();
|
hideSubjectEditor();
|
||||||
mHost.sendMessage(message);
|
if (AccessibilityUtil.isTouchExplorationEnabled(getContext())) {
|
||||||
hideSubjectEditor();
|
AccessibilityUtil.announceForAccessibilityCompat(
|
||||||
if (AccessibilityUtil.isTouchExplorationEnabled(getContext())) {
|
ComposeMessageView.this, null,
|
||||||
AccessibilityUtil.announceForAccessibilityCompat(
|
R.string.sending_message);
|
||||||
ComposeMessageView.this, null,
|
}
|
||||||
R.string.sending_message);
|
|
||||||
}
|
}
|
||||||
}
|
break;
|
||||||
break;
|
|
||||||
|
|
||||||
case CheckDraftForSendTask.RESULT_HAS_PENDING_ATTACHMENTS:
|
case CheckDraftForSendTask.RESULT_HAS_PENDING_ATTACHMENTS:
|
||||||
// Cannot send while there's still attachment(s) being loaded.
|
// Cannot send while there's still attachment(s) being loaded.
|
||||||
UiUtils.showToastAtBottom(
|
UiUtils.showToastAtBottom(
|
||||||
R.string.cant_send_message_while_loading_attachments);
|
R.string.cant_send_message_while_loading_attachments);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CheckDraftForSendTask.RESULT_NO_SELF_PHONE_NUMBER_IN_GROUP_MMS:
|
case CheckDraftForSendTask.RESULT_NO_SELF_PHONE_NUMBER_IN_GROUP_MMS:
|
||||||
mHost.promptForSelfPhoneNumber();
|
mHost.promptForSelfPhoneNumber();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CheckDraftForSendTask.RESULT_MESSAGE_OVER_LIMIT:
|
case CheckDraftForSendTask.RESULT_MESSAGE_OVER_LIMIT:
|
||||||
Assert.isTrue(checkMessageSize);
|
Assert.isTrue(checkMessageSize);
|
||||||
mHost.warnOfExceedingMessageLimit(
|
mHost.warnOfExceedingMessageLimit(
|
||||||
true /*sending*/, false /* tooManyVideos */);
|
true /*sending*/, false /* tooManyVideos */);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CheckDraftForSendTask.RESULT_VIDEO_ATTACHMENT_LIMIT_EXCEEDED:
|
case CheckDraftForSendTask.RESULT_VIDEO_ATTACHMENT_LIMIT_EXCEEDED:
|
||||||
Assert.isTrue(checkMessageSize);
|
Assert.isTrue(checkMessageSize);
|
||||||
mHost.warnOfExceedingMessageLimit(
|
mHost.warnOfExceedingMessageLimit(
|
||||||
true /*sending*/, true /* tooManyVideos */);
|
true /*sending*/, true /* tooManyVideos */);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CheckDraftForSendTask.RESULT_SIM_NOT_READY:
|
case CheckDraftForSendTask.RESULT_SIM_NOT_READY:
|
||||||
// Cannot send if there is no active subscription
|
// Cannot send if there is no active subscription
|
||||||
UiUtils.showToastAtBottom(
|
UiUtils.showToastAtBottom(
|
||||||
R.string.cant_send_message_without_active_subscription);
|
R.string.cant_send_message_without_active_subscription);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
}
|
|
||||||
}, mBinding);
|
|
||||||
} else {
|
|
||||||
mHost.warnOfMissingActionConditions(true /*sending*/,
|
|
||||||
new Runnable() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
sendMessageInternal(checkMessageSize);
|
|
||||||
}
|
}
|
||||||
|
}, mBinding);
|
||||||
});
|
} else {
|
||||||
|
mHost.warnOfMissingActionConditions(true /*sending*/, () ->
|
||||||
|
sendMessageInternal(checkMessageSize));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -110,12 +110,9 @@ public class ConversationFastScroller extends RecyclerView.OnScrollListener impl
|
|||||||
private AnimatorSet mHideAnimation;
|
private AnimatorSet mHideAnimation;
|
||||||
private ObjectAnimator mHidePreviewAnimation;
|
private ObjectAnimator mHidePreviewAnimation;
|
||||||
|
|
||||||
private final Runnable mHideTrackRunnable = new Runnable() {
|
private final Runnable mHideTrackRunnable = () -> {
|
||||||
@Override
|
hide(true /* animate */);
|
||||||
public void run() {
|
mPendingHide = false;
|
||||||
hide(true /* animate */);
|
|
||||||
mPendingHide = false;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
private ConversationFastScroller(RecyclerView rv, int position) {
|
private ConversationFastScroller(RecyclerView rv, int position) {
|
||||||
|
|||||||
@@ -28,10 +28,6 @@ import android.content.BroadcastReceiver;
|
|||||||
import android.content.ClipData;
|
import android.content.ClipData;
|
||||||
import android.content.ClipboardManager;
|
import android.content.ClipboardManager;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.DialogInterface;
|
|
||||||
import android.content.DialogInterface.OnCancelListener;
|
|
||||||
import android.content.DialogInterface.OnClickListener;
|
|
||||||
import android.content.DialogInterface.OnDismissListener;
|
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.IntentFilter;
|
import android.content.IntentFilter;
|
||||||
import android.content.res.Configuration;
|
import android.content.res.Configuration;
|
||||||
@@ -420,19 +416,13 @@ public class ConversationFragment extends Fragment implements ConversationDataLi
|
|||||||
mAdapter = new ConversationMessageAdapter(getActivity(), null, this,
|
mAdapter = new ConversationMessageAdapter(getActivity(), null, this,
|
||||||
null,
|
null,
|
||||||
// Sets the item click listener on the Recycler item views.
|
// Sets the item click listener on the Recycler item views.
|
||||||
new View.OnClickListener() {
|
v -> {
|
||||||
@Override
|
final ConversationMessageView messageView = (ConversationMessageView) v;
|
||||||
public void onClick(final View v) {
|
handleMessageClick(messageView);
|
||||||
final ConversationMessageView messageView = (ConversationMessageView) v;
|
|
||||||
handleMessageClick(messageView);
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
new View.OnLongClickListener() {
|
view -> {
|
||||||
@Override
|
selectMessage((ConversationMessageView) view);
|
||||||
public boolean onLongClick(final View view) {
|
return true;
|
||||||
selectMessage((ConversationMessageView) view);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -555,23 +545,17 @@ public class ConversationFragment extends Fragment implements ConversationDataLi
|
|||||||
|
|
||||||
view.setAlpha(0);
|
view.setAlpha(0);
|
||||||
mPopupTransitionAnimation = new PopupTransitionAnimation(startRect, view);
|
mPopupTransitionAnimation = new PopupTransitionAnimation(startRect, view);
|
||||||
mPopupTransitionAnimation.setOnStartCallback(new Runnable() {
|
mPopupTransitionAnimation.setOnStartCallback(() -> {
|
||||||
@Override
|
final int startWidth = composeBubbleRect.width();
|
||||||
public void run() {
|
attachmentView.onMessageAnimationStart();
|
||||||
final int startWidth = composeBubbleRect.width();
|
messageBubble.kickOffMorphAnimation(startWidth,
|
||||||
attachmentView.onMessageAnimationStart();
|
messageBubble.findViewById(R.id.message_text_and_info)
|
||||||
messageBubble.kickOffMorphAnimation(startWidth,
|
.getMeasuredWidth());
|
||||||
messageBubble.findViewById(R.id.message_text_and_info)
|
});
|
||||||
.getMeasuredWidth());
|
mPopupTransitionAnimation.setOnStopCallback(() -> {
|
||||||
}
|
view.setAlpha(1);
|
||||||
});
|
dispatchAddFinished(holder);
|
||||||
mPopupTransitionAnimation.setOnStopCallback(new Runnable() {
|
});
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
view.setAlpha(1);
|
|
||||||
dispatchAddFinished(holder);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
mPopupTransitionAnimation.startAfterLayoutComplete();
|
mPopupTransitionAnimation.startAfterLayoutComplete();
|
||||||
mAddAnimations.add(holder);
|
mAddAnimations.add(holder);
|
||||||
return true;
|
return true;
|
||||||
@@ -827,13 +811,7 @@ public class ConversationFragment extends Fragment implements ConversationDataLi
|
|||||||
.setTitle(getResources().getQuantityString(
|
.setTitle(getResources().getQuantityString(
|
||||||
R.plurals.delete_conversations_confirmation_dialog_title, 1))
|
R.plurals.delete_conversations_confirmation_dialog_title, 1))
|
||||||
.setPositiveButton(R.string.delete_conversation_confirmation_button,
|
.setPositiveButton(R.string.delete_conversation_confirmation_button,
|
||||||
new DialogInterface.OnClickListener() {
|
(dialog, button) -> deleteConversation())
|
||||||
@Override
|
|
||||||
public void onClick(final DialogInterface dialog,
|
|
||||||
final int button) {
|
|
||||||
deleteConversation();
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.setNegativeButton(R.string.delete_conversation_decline_button, null)
|
.setNegativeButton(R.string.delete_conversation_decline_button, null)
|
||||||
.show();
|
.show();
|
||||||
} else {
|
} else {
|
||||||
@@ -894,12 +872,9 @@ public class ConversationFragment extends Fragment implements ConversationDataLi
|
|||||||
UiUtils.showSnackBarWithCustomAction(getActivity(),
|
UiUtils.showSnackBarWithCustomAction(getActivity(),
|
||||||
getView().getRootView(),
|
getView().getRootView(),
|
||||||
getString(R.string.in_conversation_notify_new_message_text),
|
getString(R.string.in_conversation_notify_new_message_text),
|
||||||
SnackBar.Action.createCustomAction(new Runnable() {
|
SnackBar.Action.createCustomAction(() -> {
|
||||||
@Override
|
scrollToBottom(true /* smoothScroll */);
|
||||||
public void run() {
|
mComposeMessageView.hideAllComposeInputs(false /* animate */);
|
||||||
scrollToBottom(true /* smoothScroll */);
|
|
||||||
mComposeMessageView.hideAllComposeInputs(false /* animate */);
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
getString(R.string.in_conversation_notify_new_message_action)),
|
getString(R.string.in_conversation_notify_new_message_action)),
|
||||||
null /* interactions */,
|
null /* interactions */,
|
||||||
@@ -1036,13 +1011,7 @@ public class ConversationFragment extends Fragment implements ConversationDataLi
|
|||||||
LogUtil.w(LogUtil.BUGLE_TAG, "Message can't be sent: conv participants not loaded");
|
LogUtil.w(LogUtil.BUGLE_TAG, "Message can't be sent: conv participants not loaded");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
warnOfMissingActionConditions(true /*sending*/,
|
warnOfMissingActionConditions(true /*sending*/, () -> sendMessage(message));
|
||||||
new Runnable() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
sendMessage(message);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1137,14 +1106,7 @@ public class ConversationFragment extends Fragment implements ConversationDataLi
|
|||||||
mBinding.getData().resendMessage(mBinding, messageId);
|
mBinding.getData().resendMessage(mBinding, messageId);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
warnOfMissingActionConditions(true /*sending*/,
|
warnOfMissingActionConditions(true /*sending*/, () -> retrySend(messageId));
|
||||||
new Runnable() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
retrySend(messageId);
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1154,12 +1116,8 @@ public class ConversationFragment extends Fragment implements ConversationDataLi
|
|||||||
.setTitle(R.string.delete_message_confirmation_dialog_title)
|
.setTitle(R.string.delete_message_confirmation_dialog_title)
|
||||||
.setMessage(R.string.delete_message_confirmation_dialog_text)
|
.setMessage(R.string.delete_message_confirmation_dialog_text)
|
||||||
.setPositiveButton(R.string.delete_message_confirmation_button,
|
.setPositiveButton(R.string.delete_message_confirmation_button,
|
||||||
new OnClickListener() {
|
(dialog, which) ->
|
||||||
@Override
|
mBinding.getData().deleteMessage(mBinding, messageId))
|
||||||
public void onClick(final DialogInterface dialog, final int which) {
|
|
||||||
mBinding.getData().deleteMessage(mBinding, messageId);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.setNegativeButton(android.R.string.cancel, null);
|
.setNegativeButton(android.R.string.cancel, null);
|
||||||
builder.setOnDismissListener(dialog -> mHost.dismissActionMode());
|
builder.setOnDismissListener(dialog -> mHost.dismissActionMode());
|
||||||
builder.create().show();
|
builder.create().show();
|
||||||
@@ -1506,19 +1464,11 @@ public class ConversationFragment extends Fragment implements ConversationDataLi
|
|||||||
} else {
|
} else {
|
||||||
builder.setMessage(R.string.attachment_limit_reached_dialog_message_when_sending)
|
builder.setMessage(R.string.attachment_limit_reached_dialog_message_when_sending)
|
||||||
.setNegativeButton(R.string.attachment_limit_reached_send_anyway,
|
.setNegativeButton(R.string.attachment_limit_reached_send_anyway,
|
||||||
new OnClickListener() {
|
(dialog, which) ->
|
||||||
@Override
|
composeMessageView.sendMessageIgnoreMessageSizeLimit());
|
||||||
public void onClick(final DialogInterface dialog,
|
|
||||||
final int which) {
|
|
||||||
composeMessageView.sendMessageIgnoreMessageSizeLimit();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
builder.setPositiveButton(android.R.string.ok, new OnClickListener() {
|
builder.setPositiveButton(android.R.string.ok, (dialog, which) ->
|
||||||
@Override
|
showAttachmentChooser(conversationId, activity));
|
||||||
public void onClick(final DialogInterface dialog, final int which) {
|
|
||||||
showAttachmentChooser(conversationId, activity);
|
|
||||||
}});
|
|
||||||
} else {
|
} else {
|
||||||
builder.setMessage(R.string.attachment_limit_reached_dialog_message_when_composing)
|
builder.setMessage(R.string.attachment_limit_reached_dialog_message_when_composing)
|
||||||
.setPositiveButton(android.R.string.ok, null);
|
.setPositiveButton(android.R.string.ok, null);
|
||||||
@@ -1557,12 +1507,7 @@ public class ConversationFragment extends Fragment implements ConversationDataLi
|
|||||||
final LayoutInflater inflator = (LayoutInflater)
|
final LayoutInflater inflator = (LayoutInflater)
|
||||||
getActivity().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
|
getActivity().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
|
||||||
customView = inflator.inflate(R.layout.action_bar_conversation_name, null);
|
customView = inflator.inflate(R.layout.action_bar_conversation_name, null);
|
||||||
customView.setOnClickListener(new View.OnClickListener() {
|
customView.setOnClickListener(v -> onBackPressed());
|
||||||
@Override
|
|
||||||
public void onClick(final View v) {
|
|
||||||
onBackPressed();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
actionBar.setCustomView(customView);
|
actionBar.setCustomView(customView);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2015 The Android Open Source Project
|
* Copyright (C) 2015 The Android Open Source Project
|
||||||
|
* Copyright (C) 2024 The LineageOS Project
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -123,12 +124,9 @@ public class ConversationMessageView extends FrameLayout implements View.OnClick
|
|||||||
@Override
|
@Override
|
||||||
protected void onFinishInflate() {
|
protected void onFinishInflate() {
|
||||||
mContactIconView = (ContactIconView) findViewById(R.id.conversation_icon);
|
mContactIconView = (ContactIconView) findViewById(R.id.conversation_icon);
|
||||||
mContactIconView.setOnLongClickListener(new OnLongClickListener() {
|
mContactIconView.setOnLongClickListener(view -> {
|
||||||
@Override
|
ConversationMessageView.this.performLongClick();
|
||||||
public boolean onLongClick(final View view) {
|
return true;
|
||||||
ConversationMessageView.this.performLongClick();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
mMessageAttachmentsView = (LinearLayout) findViewById(R.id.message_attachments);
|
mMessageAttachmentsView = (LinearLayout) findViewById(R.id.message_attachments);
|
||||||
@@ -1044,40 +1042,13 @@ public class ConversationMessageView extends FrameLayout implements View.OnClick
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Sort photos in MultiAttachLayout in the same order as the ConversationImagePartsView
|
// Sort photos in MultiAttachLayout in the same order as the ConversationImagePartsView
|
||||||
static final Comparator<MessagePartData> sImageComparator = new Comparator<MessagePartData>(){
|
static final Comparator<MessagePartData> sImageComparator =
|
||||||
@Override
|
Comparator.comparing(MessagePartData::getPartId);
|
||||||
public int compare(final MessagePartData x, final MessagePartData y) {
|
|
||||||
return x.getPartId().compareTo(y.getPartId());
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
static final Predicate<MessagePartData> sVideoFilter = new Predicate<MessagePartData>() {
|
static final Predicate<MessagePartData> sVideoFilter = MessagePartData::isVideo;
|
||||||
@Override
|
static final Predicate<MessagePartData> sAudioFilter = MessagePartData::isAudio;
|
||||||
public boolean apply(final MessagePartData part) {
|
static final Predicate<MessagePartData> sVCardFilter = MessagePartData::isVCard;
|
||||||
return part.isVideo();
|
static final Predicate<MessagePartData> sImageFilter = MessagePartData::isImage;
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
static final Predicate<MessagePartData> sAudioFilter = new Predicate<MessagePartData>() {
|
|
||||||
@Override
|
|
||||||
public boolean apply(final MessagePartData part) {
|
|
||||||
return part.isAudio();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
static final Predicate<MessagePartData> sVCardFilter = new Predicate<MessagePartData>() {
|
|
||||||
@Override
|
|
||||||
public boolean apply(final MessagePartData part) {
|
|
||||||
return part.isVCard();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
static final Predicate<MessagePartData> sImageFilter = new Predicate<MessagePartData>() {
|
|
||||||
@Override
|
|
||||||
public boolean apply(final MessagePartData part) {
|
|
||||||
return part.isImage();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
interface AttachmentViewBinder {
|
interface AttachmentViewBinder {
|
||||||
void bindView(View view, MessagePartData attachment);
|
void bindView(View view, MessagePartData attachment);
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2015 The Android Open Source Project
|
* Copyright (C) 2015 The Android Open Source Project
|
||||||
|
* Copyright (C) 2024 The LineageOS Project
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -48,13 +49,10 @@ abstract class ConversationSimSelector extends ConversationInput {
|
|||||||
if (mPendingShow != null && mDataReady) {
|
if (mPendingShow != null && mDataReady) {
|
||||||
final boolean show = mPendingShow.first;
|
final boolean show = mPendingShow.first;
|
||||||
final boolean animate = mPendingShow.second;
|
final boolean animate = mPendingShow.second;
|
||||||
ThreadUtil.getMainThreadHandler().post(new Runnable() {
|
ThreadUtil.getMainThreadHandler().post(() -> {
|
||||||
@Override
|
// This will No-Op if we are no longer attached to the host.
|
||||||
public void run() {
|
mConversationInputBase.showHideInternal(ConversationSimSelector.this,
|
||||||
// This will No-Op if we are no longer attached to the host.
|
show, animate);
|
||||||
mConversationInputBase.showHideInternal(ConversationSimSelector.this,
|
|
||||||
show, animate);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
mPendingShow = null;
|
mPendingShow = null;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2015 The Android Open Source Project
|
* Copyright (C) 2015 The Android Open Source Project
|
||||||
|
* Copyright (C) 2024 The LineageOS Project
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -19,7 +20,6 @@ import android.app.AlertDialog;
|
|||||||
import android.app.Dialog;
|
import android.app.Dialog;
|
||||||
import android.app.DialogFragment;
|
import android.app.DialogFragment;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.DialogInterface;
|
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
@@ -53,30 +53,18 @@ public class EnterSelfPhoneNumberDialog extends DialogFragment {
|
|||||||
builder.setTitle(R.string.enter_phone_number_title)
|
builder.setTitle(R.string.enter_phone_number_title)
|
||||||
.setMessage(R.string.enter_phone_number_text)
|
.setMessage(R.string.enter_phone_number_text)
|
||||||
.setView(mEditText)
|
.setView(mEditText)
|
||||||
.setNegativeButton(android.R.string.cancel,
|
.setNegativeButton(android.R.string.cancel, (dialog, button) -> dismiss())
|
||||||
new DialogInterface.OnClickListener() {
|
.setPositiveButton(android.R.string.ok, (dialog, button) -> {
|
||||||
@Override
|
final String newNumber = mEditText.getText().toString();
|
||||||
public void onClick(final DialogInterface dialog,
|
dismiss();
|
||||||
final int button) {
|
if (!TextUtils.isEmpty(newNumber)) {
|
||||||
dismiss();
|
savePhoneNumberInPrefs(newNumber);
|
||||||
}
|
// TODO: Remove this toast and just auto-send
|
||||||
})
|
// the message instead
|
||||||
.setPositiveButton(android.R.string.ok,
|
UiUtils.showToast(
|
||||||
new DialogInterface.OnClickListener() {
|
R.string
|
||||||
@Override
|
.toast_after_setting_default_sms_app_for_message_send);
|
||||||
public void onClick(final DialogInterface dialog,
|
}
|
||||||
final int button) {
|
|
||||||
final String newNumber = mEditText.getText().toString();
|
|
||||||
dismiss();
|
|
||||||
if (!TextUtils.isEmpty(newNumber)) {
|
|
||||||
savePhoneNumberInPrefs(newNumber);
|
|
||||||
// TODO: Remove this toast and just auto-send
|
|
||||||
// the message instead
|
|
||||||
UiUtils.showToast(
|
|
||||||
R.string
|
|
||||||
.toast_after_setting_default_sms_app_for_message_send);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
return builder.create();
|
return builder.create();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2015 The Android Open Source Project
|
* Copyright (C) 2015 The Android Open Source Project
|
||||||
|
* Copyright (C) 2024 The LineageOS Project
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -18,7 +19,6 @@ package com.android.messaging.ui.conversation;
|
|||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
import android.util.AttributeSet;
|
import android.util.AttributeSet;
|
||||||
import android.view.View;
|
|
||||||
import android.widget.LinearLayout;
|
import android.widget.LinearLayout;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
@@ -49,12 +49,7 @@ public class SimSelectorItemView extends LinearLayout {
|
|||||||
mNameTextView = (TextView) findViewById(R.id.name);
|
mNameTextView = (TextView) findViewById(R.id.name);
|
||||||
mDetailsTextView = (TextView) findViewById(R.id.details);
|
mDetailsTextView = (TextView) findViewById(R.id.details);
|
||||||
mSimIconView = (SimIconView) findViewById(R.id.sim_icon);
|
mSimIconView = (SimIconView) findViewById(R.id.sim_icon);
|
||||||
setOnClickListener(new OnClickListener() {
|
setOnClickListener(v -> mHost.onSimItemClicked(mData));
|
||||||
@Override
|
|
||||||
public void onClick(View v) {
|
|
||||||
mHost.onSimItemClicked(mData);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void bind(final SubscriptionListEntry simEntry) {
|
public void bind(final SubscriptionListEntry simEntry) {
|
||||||
|
|||||||
@@ -64,12 +64,7 @@ public class SimSelectorView extends FrameLayout implements SimSelectorItemView.
|
|||||||
mSimListView.setAdapter(mAdapter);
|
mSimListView.setAdapter(mAdapter);
|
||||||
|
|
||||||
// Clicking anywhere outside the switcher list should dismiss.
|
// Clicking anywhere outside the switcher list should dismiss.
|
||||||
setOnClickListener(new OnClickListener() {
|
setOnClickListener(v -> showOrHide(false, true));
|
||||||
@Override
|
|
||||||
public void onClick(View v) {
|
|
||||||
showOrHide(false, true);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void bind(final SubscriptionListData data) {
|
public void bind(final SubscriptionListData data) {
|
||||||
@@ -102,12 +97,9 @@ public class SimSelectorView extends FrameLayout implements SimSelectorItemView.
|
|||||||
setAlpha(mShow ? 0.0f : 1.0f);
|
setAlpha(mShow ? 0.0f : 1.0f);
|
||||||
animate().alpha(mShow ? 1.0f : 0.0f)
|
animate().alpha(mShow ? 1.0f : 0.0f)
|
||||||
.setDuration(UiUtils.REVEAL_ANIMATION_DURATION)
|
.setDuration(UiUtils.REVEAL_ANIMATION_DURATION)
|
||||||
.withEndAction(new Runnable() {
|
.withEndAction(() -> {
|
||||||
@Override
|
setAlpha(1.0f);
|
||||||
public void run() {
|
setVisibility(mShow ? VISIBLE : GONE);
|
||||||
setAlpha(1.0f);
|
|
||||||
setVisibility(mShow ? VISIBLE : GONE);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
setVisibility(mShow ? VISIBLE : GONE);
|
setVisibility(mShow ? VISIBLE : GONE);
|
||||||
|
|||||||
+42
-59
@@ -1,5 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2015 The Android Open Source Project
|
* Copyright (C) 2015 The Android Open Source Project
|
||||||
|
* Copyright (C) 2024 The LineageOS Project
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -19,7 +20,6 @@ import android.app.Activity;
|
|||||||
import android.app.AlertDialog;
|
import android.app.AlertDialog;
|
||||||
import android.app.Fragment;
|
import android.app.Fragment;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.DialogInterface;
|
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.res.Resources;
|
import android.content.res.Resources;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
@@ -118,14 +118,11 @@ public abstract class AbstractConversationListActivity extends BugleActionBarAc
|
|||||||
UiUtils.showSnackBarWithCustomAction(this,
|
UiUtils.showSnackBarWithCustomAction(this,
|
||||||
getWindow().getDecorView().getRootView(),
|
getWindow().getDecorView().getRootView(),
|
||||||
getString(R.string.requires_default_sms_app),
|
getString(R.string.requires_default_sms_app),
|
||||||
SnackBar.Action.createCustomAction(new Runnable() {
|
SnackBar.Action.createCustomAction(() -> {
|
||||||
@Override
|
final Intent intent =
|
||||||
public void run() {
|
UIIntents.get().getChangeDefaultSmsAppIntent(activity);
|
||||||
final Intent intent =
|
startActivityForResult(intent, REQUEST_SET_DEFAULT_SMS_APP);
|
||||||
UIIntents.get().getChangeDefaultSmsAppIntent(activity);
|
},
|
||||||
startActivityForResult(intent, REQUEST_SET_DEFAULT_SMS_APP);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
getString(R.string.requires_default_sms_change_button)),
|
getString(R.string.requires_default_sms_change_button)),
|
||||||
null /* interactions */,
|
null /* interactions */,
|
||||||
null /* placement */);
|
null /* placement */);
|
||||||
@@ -137,18 +134,14 @@ public abstract class AbstractConversationListActivity extends BugleActionBarAc
|
|||||||
R.plurals.delete_conversations_confirmation_dialog_title,
|
R.plurals.delete_conversations_confirmation_dialog_title,
|
||||||
conversations.size()))
|
conversations.size()))
|
||||||
.setPositiveButton(R.string.delete_conversation_confirmation_button,
|
.setPositiveButton(R.string.delete_conversation_confirmation_button,
|
||||||
new DialogInterface.OnClickListener() {
|
(dialog, button) -> {
|
||||||
@Override
|
for (final SelectedConversation conversation : conversations) {
|
||||||
public void onClick(final DialogInterface dialog,
|
DeleteConversationAction.deleteConversation(
|
||||||
final int button) {
|
conversation.conversationId,
|
||||||
for (final SelectedConversation conversation : conversations) {
|
conversation.timestamp);
|
||||||
DeleteConversationAction.deleteConversation(
|
|
||||||
conversation.conversationId,
|
|
||||||
conversation.timestamp);
|
|
||||||
}
|
|
||||||
exitMultiSelectState();
|
|
||||||
}
|
}
|
||||||
})
|
exitMultiSelectState();
|
||||||
|
})
|
||||||
.setNegativeButton(R.string.delete_conversation_decline_button, null)
|
.setNegativeButton(R.string.delete_conversation_decline_button, null)
|
||||||
.show();
|
.show();
|
||||||
}
|
}
|
||||||
@@ -167,15 +160,12 @@ public abstract class AbstractConversationListActivity extends BugleActionBarAc
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
final Runnable undoRunnable = new Runnable() {
|
final Runnable undoRunnable = () -> {
|
||||||
@Override
|
for (final String conversationId : conversationIds) {
|
||||||
public void run() {
|
if (isToArchive) {
|
||||||
for (final String conversationId : conversationIds) {
|
UpdateConversationArchiveStatusAction.unarchiveConversation(conversationId);
|
||||||
if (isToArchive) {
|
} else {
|
||||||
UpdateConversationArchiveStatusAction.unarchiveConversation(conversationId);
|
UpdateConversationArchiveStatusAction.archiveConversation(conversationId);
|
||||||
} else {
|
|
||||||
UpdateConversationArchiveStatusAction.archiveConversation(conversationId);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -211,36 +201,29 @@ public abstract class AbstractConversationListActivity extends BugleActionBarAc
|
|||||||
conversation.otherParticipantNormalizedDestination))
|
conversation.otherParticipantNormalizedDestination))
|
||||||
.setMessage(res.getString(R.string.block_confirmation_message))
|
.setMessage(res.getString(R.string.block_confirmation_message))
|
||||||
.setNegativeButton(android.R.string.cancel, null)
|
.setNegativeButton(android.R.string.cancel, null)
|
||||||
.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
|
.setPositiveButton(android.R.string.ok, (arg0, arg1) -> {
|
||||||
@Override
|
final Context context = AbstractConversationListActivity.this;
|
||||||
public void onClick(final DialogInterface arg0, final int arg1) {
|
final View listView = findViewById(android.R.id.list);
|
||||||
final Context context = AbstractConversationListActivity.this;
|
final List<SnackBarInteraction> interactions =
|
||||||
final View listView = findViewById(android.R.id.list);
|
mConversationListFragment.getSnackBarInteractions();
|
||||||
final List<SnackBarInteraction> interactions =
|
final UpdateDestinationBlockedAction.UpdateDestinationBlockedActionListener
|
||||||
mConversationListFragment.getSnackBarInteractions();
|
undoListener =
|
||||||
final UpdateDestinationBlockedAction.UpdateDestinationBlockedActionListener
|
new UpdateDestinationBlockedActionSnackBar(
|
||||||
undoListener =
|
context, listView, null /* undoRunnable */,
|
||||||
new UpdateDestinationBlockedActionSnackBar(
|
interactions);
|
||||||
context, listView, null /* undoRunnable */,
|
final Runnable undoRunnable = () ->
|
||||||
interactions);
|
UpdateDestinationBlockedAction.updateDestinationBlocked(
|
||||||
final Runnable undoRunnable = new Runnable() {
|
conversation.otherParticipantNormalizedDestination, false,
|
||||||
@Override
|
conversation.conversationId,
|
||||||
public void run() {
|
undoListener);
|
||||||
UpdateDestinationBlockedAction.updateDestinationBlocked(
|
final UpdateDestinationBlockedAction.UpdateDestinationBlockedActionListener
|
||||||
conversation.otherParticipantNormalizedDestination, false,
|
listener = new UpdateDestinationBlockedActionSnackBar(
|
||||||
conversation.conversationId,
|
context, listView, undoRunnable, interactions);
|
||||||
undoListener);
|
UpdateDestinationBlockedAction.updateDestinationBlocked(
|
||||||
}
|
conversation.otherParticipantNormalizedDestination, true,
|
||||||
};
|
conversation.conversationId,
|
||||||
final UpdateDestinationBlockedAction.UpdateDestinationBlockedActionListener
|
listener);
|
||||||
listener = new UpdateDestinationBlockedActionSnackBar(
|
exitMultiSelectState();
|
||||||
context, listView, undoRunnable, interactions);
|
|
||||||
UpdateDestinationBlockedAction.updateDestinationBlocked(
|
|
||||||
conversation.otherParticipantNormalizedDestination, true,
|
|
||||||
conversation.conversationId,
|
|
||||||
listener);
|
|
||||||
exitMultiSelectState();
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
.create()
|
.create()
|
||||||
.show();
|
.show();
|
||||||
|
|||||||
@@ -35,7 +35,6 @@ import android.view.Menu;
|
|||||||
import android.view.MenuInflater;
|
import android.view.MenuInflater;
|
||||||
import android.view.MenuItem;
|
import android.view.MenuItem;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.View.OnClickListener;
|
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.view.ViewGroup.MarginLayoutParams;
|
import android.view.ViewGroup.MarginLayoutParams;
|
||||||
import android.view.ViewPropertyAnimator;
|
import android.view.ViewPropertyAnimator;
|
||||||
@@ -229,12 +228,8 @@ public class ConversationListFragment extends Fragment implements ConversationLi
|
|||||||
mStartNewConversationButton.setVisibility(View.GONE);
|
mStartNewConversationButton.setVisibility(View.GONE);
|
||||||
} else {
|
} else {
|
||||||
mStartNewConversationButton.setVisibility(View.VISIBLE);
|
mStartNewConversationButton.setVisibility(View.VISIBLE);
|
||||||
mStartNewConversationButton.setOnClickListener(new OnClickListener() {
|
mStartNewConversationButton.setOnClickListener(clickView ->
|
||||||
@Override
|
mHost.onCreateConversationClick());
|
||||||
public void onClick(final View clickView) {
|
|
||||||
mHost.onCreateConversationClick();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
ViewCompat.setTransitionName(mStartNewConversationButton, BugleAnimationTags.TAG_FABICON);
|
ViewCompat.setTransitionName(mStartNewConversationButton, BugleAnimationTags.TAG_FABICON);
|
||||||
|
|
||||||
@@ -415,12 +410,9 @@ public class ConversationListFragment extends Fragment implements ConversationLi
|
|||||||
}
|
}
|
||||||
|
|
||||||
public ViewPropertyAnimator showFab() {
|
public ViewPropertyAnimator showFab() {
|
||||||
return getNormalizedFabAnimator().translationX(0).withEndAction(new Runnable() {
|
return getNormalizedFabAnimator().translationX(0).withEndAction(() -> {
|
||||||
@Override
|
// Re-enable clicks after the animation.
|
||||||
public void run() {
|
mStartNewConversationButton.setEnabled(true);
|
||||||
// Re-enable clicks after the animation.
|
|
||||||
mStartNewConversationButton.setEnabled(true);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2015 The Android Open Source Project
|
* Copyright (C) 2015 The Android Open Source Project
|
||||||
|
* Copyright (C) 2024 The LineageOS Project
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -552,12 +553,8 @@ public class ConversationListItemView extends FrameLayout implements OnClickList
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
UpdateConversationArchiveStatusAction.archiveConversation(conversationId);
|
UpdateConversationArchiveStatusAction.archiveConversation(conversationId);
|
||||||
final Runnable undoRunnable = new Runnable() {
|
final Runnable undoRunnable = () ->
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
UpdateConversationArchiveStatusAction.unarchiveConversation(conversationId);
|
UpdateConversationArchiveStatusAction.unarchiveConversation(conversationId);
|
||||||
}
|
|
||||||
};
|
|
||||||
final String message = getResources().getString(R.string.archived_toast_message, 1);
|
final String message = getResources().getString(R.string.archived_toast_message, 1);
|
||||||
UiUtils.showSnackBar(getContext(), getRootView(), message, undoRunnable,
|
UiUtils.showSnackBar(getContext(), getRootView(), message, undoRunnable,
|
||||||
SnackBar.Action.SNACK_BAR_UNDO,
|
SnackBar.Action.SNACK_BAR_UNDO,
|
||||||
|
|||||||
@@ -22,7 +22,6 @@ import android.app.AlertDialog.Builder;
|
|||||||
import android.app.Dialog;
|
import android.app.Dialog;
|
||||||
import android.app.DialogFragment;
|
import android.app.DialogFragment;
|
||||||
import android.content.DialogInterface;
|
import android.content.DialogInterface;
|
||||||
import android.content.DialogInterface.OnClickListener;
|
|
||||||
import android.database.Cursor;
|
import android.database.Cursor;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||||
@@ -92,13 +91,10 @@ public class ShareIntentFragment extends DialogFragment implements ConversationL
|
|||||||
|
|
||||||
final Bundle arguments = getArguments();
|
final Bundle arguments = getArguments();
|
||||||
if (arguments == null || !arguments.getBoolean(HIDE_NEW_CONVERSATION_BUTTON_KEY)) {
|
if (arguments == null || !arguments.getBoolean(HIDE_NEW_CONVERSATION_BUTTON_KEY)) {
|
||||||
dialogBuilder.setPositiveButton(R.string.share_new_message, new OnClickListener() {
|
dialogBuilder.setPositiveButton(R.string.share_new_message, (dialog, which) -> {
|
||||||
@Override
|
mDismissed = true;
|
||||||
public void onClick(DialogInterface dialog, int which) {
|
mHost.onCreateConversationClick();
|
||||||
mDismissed = true;
|
});
|
||||||
mHost.onCreateConversationClick();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
return dialogBuilder.setNegativeButton(R.string.share_cancel, null)
|
return dialogBuilder.setNegativeButton(R.string.share_cancel, null)
|
||||||
.create();
|
.create();
|
||||||
|
|||||||
@@ -21,7 +21,6 @@ import android.app.AlertDialog;
|
|||||||
import android.app.Fragment;
|
import android.app.Fragment;
|
||||||
import android.app.NotificationManager;
|
import android.app.NotificationManager;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.DialogInterface;
|
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.res.Resources;
|
import android.content.res.Resources;
|
||||||
import android.database.Cursor;
|
import android.database.Cursor;
|
||||||
@@ -156,14 +155,10 @@ public class PeopleAndOptionsFragment extends Fragment
|
|||||||
item.getOtherParticipant().getDisplayDestination()))
|
item.getOtherParticipant().getDisplayDestination()))
|
||||||
.setMessage(res.getString(R.string.block_confirmation_message))
|
.setMessage(res.getString(R.string.block_confirmation_message))
|
||||||
.setNegativeButton(android.R.string.cancel, null)
|
.setNegativeButton(android.R.string.cancel, null)
|
||||||
.setPositiveButton(android.R.string.ok,
|
.setPositiveButton(android.R.string.ok, (arg0, arg1) -> {
|
||||||
new DialogInterface.OnClickListener() {
|
mBinding.getData().setDestinationBlocked(mBinding, true);
|
||||||
@Override
|
activity.setResult(ConversationActivity.FINISH_RESULT_CODE);
|
||||||
public void onClick(DialogInterface arg0, int arg1) {
|
activity.finish();
|
||||||
mBinding.getData().setDestinationBlocked(mBinding, true);
|
|
||||||
activity.setResult(ConversationActivity.FINISH_RESULT_CODE);
|
|
||||||
activity.finish();
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
.create()
|
.create()
|
||||||
.show();
|
.show();
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2015 The Android Open Source Project
|
* Copyright (C) 2015 The Android Open Source Project
|
||||||
|
* Copyright (C) 2024 The LineageOS Project
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -20,7 +21,6 @@ import android.database.Cursor;
|
|||||||
import androidx.appcompat.widget.SwitchCompat;
|
import androidx.appcompat.widget.SwitchCompat;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
import android.util.AttributeSet;
|
import android.util.AttributeSet;
|
||||||
import android.view.View;
|
|
||||||
import android.widget.LinearLayout;
|
import android.widget.LinearLayout;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
@@ -55,12 +55,7 @@ public class PeopleOptionsItemView extends LinearLayout {
|
|||||||
@Override
|
@Override
|
||||||
protected void onFinishInflate () {
|
protected void onFinishInflate () {
|
||||||
mTitle = (TextView) findViewById(R.id.title);
|
mTitle = (TextView) findViewById(R.id.title);
|
||||||
setOnClickListener(new OnClickListener() {
|
setOnClickListener(v -> mHostInterface.onOptionsItemViewClicked(mData));
|
||||||
@Override
|
|
||||||
public void onClick(final View v) {
|
|
||||||
mHostInterface.onOptionsItemViewClicked(mData);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void bind(final Cursor cursor, final int columnIndex, ParticipantData otherParticipant,
|
public void bind(final Cursor cursor, final int columnIndex, ParticipantData otherParticipant,
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2015 The Android Open Source Project
|
* Copyright (C) 2015 The Android Open Source Project
|
||||||
|
* Copyright (C) 2024 The LineageOS Project
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -18,7 +19,6 @@ package com.android.messaging.ui.debug;
|
|||||||
import android.app.AlertDialog;
|
import android.app.AlertDialog;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.DialogInterface;
|
import android.content.DialogInterface;
|
||||||
import android.content.DialogInterface.OnShowListener;
|
|
||||||
import android.text.InputType;
|
import android.text.InputType;
|
||||||
import android.util.AttributeSet;
|
import android.util.AttributeSet;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
@@ -115,14 +115,11 @@ public class DebugMmsConfigItemView extends LinearLayout implements OnClickListe
|
|||||||
.setPositiveButton(android.R.string.ok, this)
|
.setPositiveButton(android.R.string.ok, this)
|
||||||
.setNegativeButton(android.R.string.cancel, null)
|
.setNegativeButton(android.R.string.cancel, null)
|
||||||
.create();
|
.create();
|
||||||
dialog.setOnShowListener(new OnShowListener() {
|
dialog.setOnShowListener(dialog1 -> {
|
||||||
@Override
|
mEditText.requestFocus();
|
||||||
public void onShow(DialogInterface dialog) {
|
mEditText.selectAll();
|
||||||
mEditText.requestFocus();
|
((InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE))
|
||||||
mEditText.selectAll();
|
.toggleSoftInput(InputMethodManager.SHOW_IMPLICIT, 0);
|
||||||
((InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE))
|
|
||||||
.toggleSoftInput(InputMethodManager.SHOW_IMPLICIT, 0);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
dialog.show();
|
dialog.show();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,7 +29,6 @@ import android.os.Environment;
|
|||||||
import android.telephony.SmsMessage;
|
import android.telephony.SmsMessage;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.View.OnClickListener;
|
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.widget.ArrayAdapter;
|
import android.widget.ArrayAdapter;
|
||||||
import android.widget.ListView;
|
import android.widget.ListView;
|
||||||
@@ -113,15 +112,12 @@ public class DebugSmsMmsFromDumpFileDialogFragment extends DialogFragment {
|
|||||||
|
|
||||||
final String file = getItem(position);
|
final String file = getItem(position);
|
||||||
actionItemView.setText(file);
|
actionItemView.setText(file);
|
||||||
actionItemView.setOnClickListener(new OnClickListener() {
|
actionItemView.setOnClickListener(view1 -> {
|
||||||
@Override
|
dismiss();
|
||||||
public void onClick(final View view) {
|
if (ACTION_LOAD.equals(mAction)) {
|
||||||
dismiss();
|
receiveFromDumpFile(file);
|
||||||
if (ACTION_LOAD.equals(mAction)) {
|
} else if (ACTION_EMAIL.equals(mAction)) {
|
||||||
receiveFromDumpFile(file);
|
emailDumpFile(file);
|
||||||
} else if (ACTION_EMAIL.equals(mAction)) {
|
|
||||||
emailDumpFile(file);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return actionItemView;
|
return actionItemView;
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2015 The Android Open Source Project
|
* Copyright (C) 2015 The Android Open Source Project
|
||||||
|
* Copyright (C) 2024 The LineageOS Project
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -121,23 +122,20 @@ public class AudioRecordView extends FrameLayout implements
|
|||||||
mHintTextView = (TextView) findViewById(R.id.hint_text);
|
mHintTextView = (TextView) findViewById(R.id.hint_text);
|
||||||
mTimerTextView = (PausableChronometer) findViewById(R.id.timer_text);
|
mTimerTextView = (PausableChronometer) findViewById(R.id.timer_text);
|
||||||
mSoundLevels.setLevelSource(mMediaRecorder.getLevelSource());
|
mSoundLevels.setLevelSource(mMediaRecorder.getLevelSource());
|
||||||
mRecordButton.setOnTouchListener(new OnTouchListener() {
|
mRecordButton.setOnTouchListener((v, event) -> {
|
||||||
@Override
|
final int action = event.getActionMasked();
|
||||||
public boolean onTouch(final View v, final MotionEvent event) {
|
switch (action) {
|
||||||
final int action = event.getActionMasked();
|
case MotionEvent.ACTION_DOWN:
|
||||||
switch (action) {
|
onRecordButtonTouchDown();
|
||||||
case MotionEvent.ACTION_DOWN:
|
|
||||||
onRecordButtonTouchDown();
|
|
||||||
|
|
||||||
// Don't let the record button handle the down event to let it fall through
|
// Don't let the record button handle the down event to let it fall through
|
||||||
// so that we can handle it for the entire panel in onTouchEvent(). This is
|
// so that we can handle it for the entire panel in onTouchEvent(). This is
|
||||||
// done so that: 1) the user taps on the record button to start recording
|
// done so that: 1) the user taps on the record button to start recording
|
||||||
// 2) the entire panel owns the touch event so we'd keep recording even
|
// 2) the entire panel owns the touch event so we'd keep recording even
|
||||||
// if the user moves outside the button region.
|
// if the user moves outside the button region.
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -242,18 +240,15 @@ public class AudioRecordView extends FrameLayout implements
|
|||||||
boolean onRecordButtonTouchDown() {
|
boolean onRecordButtonTouchDown() {
|
||||||
if (!mMediaRecorder.isRecording() && mCurrentMode == MODE_IDLE) {
|
if (!mMediaRecorder.isRecording() && mCurrentMode == MODE_IDLE) {
|
||||||
setMode(MODE_STARTING);
|
setMode(MODE_STARTING);
|
||||||
playAudioStartSound(new OnCompletionListener() {
|
playAudioStartSound(() -> {
|
||||||
@Override
|
// Double-check the current mode before recording since the user may have
|
||||||
public void onCompletion() {
|
// lifted finger from the button before the beeping sound is played through.
|
||||||
// Double-check the current mode before recording since the user may have
|
final int maxSize = MmsConfig.get(mHostInterface.getConversationSelfSubId())
|
||||||
// lifted finger from the button before the beeping sound is played through.
|
.getMaxMessageSize();
|
||||||
final int maxSize = MmsConfig.get(mHostInterface.getConversationSelfSubId())
|
if (mCurrentMode == MODE_STARTING &&
|
||||||
.getMaxMessageSize();
|
mMediaRecorder.startRecording(AudioRecordView.this,
|
||||||
if (mCurrentMode == MODE_STARTING &&
|
AudioRecordView.this, maxSize)) {
|
||||||
mMediaRecorder.startRecording(AudioRecordView.this,
|
setMode(MODE_RECORDING);
|
||||||
AudioRecordView.this, maxSize)) {
|
|
||||||
setMode(MODE_RECORDING);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
mAudioRecordStartTimeMillis = System.currentTimeMillis();
|
mAudioRecordStartTimeMillis = System.currentTimeMillis();
|
||||||
@@ -270,25 +265,17 @@ public class AudioRecordView extends FrameLayout implements
|
|||||||
// "tap+hold" to record audio.
|
// "tap+hold" to record audio.
|
||||||
final Uri outputUri = stopRecording();
|
final Uri outputUri = stopRecording();
|
||||||
if (outputUri != null) {
|
if (outputUri != null) {
|
||||||
SafeAsyncTask.executeOnThreadPool(new Runnable() {
|
SafeAsyncTask.executeOnThreadPool(() ->
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
Factory.get().getApplicationContext().getContentResolver().delete(
|
Factory.get().getApplicationContext().getContentResolver().delete(
|
||||||
outputUri, null, null);
|
outputUri, null, null));
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
setMode(MODE_IDLE);
|
setMode(MODE_IDLE);
|
||||||
mHintTextView.setTypeface(null, Typeface.BOLD);
|
mHintTextView.setTypeface(null, Typeface.BOLD);
|
||||||
} else if (isRecording()) {
|
} else if (isRecording()) {
|
||||||
// Record for some extra time to ensure the ending part is saved.
|
// Record for some extra time to ensure the ending part is saved.
|
||||||
setMode(MODE_STOPPING);
|
setMode(MODE_STOPPING);
|
||||||
ThreadUtil.getMainThreadHandler().postDelayed(new Runnable() {
|
ThreadUtil.getMainThreadHandler().postDelayed(this::onFinishedRecording,
|
||||||
@Override
|
AUDIO_RECORD_ENDING_BUFFER_MILLIS);
|
||||||
public void run() {
|
|
||||||
onFinishedRecording();
|
|
||||||
}
|
|
||||||
}, AUDIO_RECORD_ENDING_BUFFER_MILLIS);
|
|
||||||
} else {
|
} else {
|
||||||
setMode(MODE_IDLE);
|
setMode(MODE_IDLE);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -35,7 +35,6 @@ import android.util.DisplayMetrics;
|
|||||||
import android.view.MotionEvent;
|
import android.view.MotionEvent;
|
||||||
import android.view.OrientationEventListener;
|
import android.view.OrientationEventListener;
|
||||||
import android.view.Surface;
|
import android.view.Surface;
|
||||||
import android.view.View;
|
|
||||||
import android.view.WindowManager;
|
import android.view.WindowManager;
|
||||||
|
|
||||||
import com.android.messaging.datamodel.data.DraftMessageData.DraftMessageSubscriptionDataProvider;
|
import com.android.messaging.datamodel.data.DraftMessageData.DraftMessageSubscriptionDataProvider;
|
||||||
@@ -268,18 +267,15 @@ class CameraManager implements FocusOverlayManager.Listener {
|
|||||||
|
|
||||||
if (preview != null) {
|
if (preview != null) {
|
||||||
Assert.isTrue(preview.isValid());
|
Assert.isTrue(preview.isValid());
|
||||||
preview.setOnTouchListener(new View.OnTouchListener() {
|
preview.setOnTouchListener((view, motionEvent) -> {
|
||||||
@Override
|
if ((motionEvent.getActionMasked() & MotionEvent.ACTION_UP) ==
|
||||||
public boolean onTouch(final View view, final MotionEvent motionEvent) {
|
MotionEvent.ACTION_UP) {
|
||||||
if ((motionEvent.getActionMasked() & MotionEvent.ACTION_UP) ==
|
mFocusOverlayManager.setPreviewSize(view.getWidth(), view.getHeight());
|
||||||
MotionEvent.ACTION_UP) {
|
mFocusOverlayManager.onSingleTapUp(
|
||||||
mFocusOverlayManager.setPreviewSize(view.getWidth(), view.getHeight());
|
(int) motionEvent.getX() + view.getLeft(),
|
||||||
mFocusOverlayManager.onSingleTapUp(
|
(int) motionEvent.getY() + view.getTop());
|
||||||
(int) motionEvent.getX() + view.getLeft(),
|
|
||||||
(int) motionEvent.getY() + view.getTop());
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
mCameraPreview = preview;
|
mCameraPreview = preview;
|
||||||
@@ -542,36 +538,33 @@ class CameraManager implements FocusOverlayManager.Listener {
|
|||||||
callback.onMediaFailed(null);
|
callback.onMediaFailed(null);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
final Camera.PictureCallback jpegCallback = new Camera.PictureCallback() {
|
final Camera.PictureCallback jpegCallback = (bytes, camera) -> {
|
||||||
@Override
|
mTakingPicture = false;
|
||||||
public void onPictureTaken(final byte[] bytes, final Camera camera) {
|
if (mCamera != camera) {
|
||||||
mTakingPicture = false;
|
// This may happen if the camera was changed between front/back while the
|
||||||
if (mCamera != camera) {
|
// picture is being taken.
|
||||||
// This may happen if the camera was changed between front/back while the
|
callback.onMediaInfo(MediaCallback.MEDIA_CAMERA_CHANGED);
|
||||||
// picture is being taken.
|
return;
|
||||||
callback.onMediaInfo(MediaCallback.MEDIA_CAMERA_CHANGED);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (bytes == null) {
|
|
||||||
callback.onMediaInfo(MediaCallback.MEDIA_NO_DATA);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
final Camera.Size size = camera.getParameters().getPictureSize();
|
|
||||||
int width;
|
|
||||||
int height;
|
|
||||||
if (mRotation == 90 || mRotation == 270) {
|
|
||||||
width = size.height;
|
|
||||||
height = size.width;
|
|
||||||
} else {
|
|
||||||
width = size.width;
|
|
||||||
height = size.height;
|
|
||||||
}
|
|
||||||
new ImagePersistTask(
|
|
||||||
width, height, heightPercent, bytes, mCameraPreview.getContext(), callback)
|
|
||||||
.executeOnThreadPool();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (bytes == null) {
|
||||||
|
callback.onMediaInfo(MediaCallback.MEDIA_NO_DATA);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
final Camera.Size size = camera.getParameters().getPictureSize();
|
||||||
|
int width;
|
||||||
|
int height;
|
||||||
|
if (mRotation == 90 || mRotation == 270) {
|
||||||
|
width = size.height;
|
||||||
|
height = size.width;
|
||||||
|
} else {
|
||||||
|
width = size.width;
|
||||||
|
height = size.height;
|
||||||
|
}
|
||||||
|
new ImagePersistTask(
|
||||||
|
width, height, heightPercent, bytes, mCameraPreview.getContext(), callback)
|
||||||
|
.executeOnThreadPool();
|
||||||
};
|
};
|
||||||
|
|
||||||
mTakingPicture = true;
|
mTakingPicture = true;
|
||||||
@@ -757,12 +750,8 @@ class CameraManager implements FocusOverlayManager.Listener {
|
|||||||
mCamera.setParameters(params);
|
mCamera.setParameters(params);
|
||||||
mCameraPreview.startPreview(mCamera);
|
mCameraPreview.startPreview(mCamera);
|
||||||
mCamera.startPreview();
|
mCamera.startPreview();
|
||||||
mCamera.setAutoFocusMoveCallback(new Camera.AutoFocusMoveCallback() {
|
mCamera.setAutoFocusMoveCallback((start, camera) ->
|
||||||
@Override
|
mFocusOverlayManager.onAutoFocusMoving(start));
|
||||||
public void onAutoFocusMoving(final boolean start, final Camera camera) {
|
|
||||||
mFocusOverlayManager.onAutoFocusMoving(start);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
mFocusOverlayManager.setParameters(mCamera.getParameters());
|
mFocusOverlayManager.setParameters(mCamera.getParameters());
|
||||||
mFocusOverlayManager.setMirror(mCameraInfo.facing == CameraInfo.CAMERA_FACING_BACK);
|
mFocusOverlayManager.setMirror(mCameraInfo.facing == CameraInfo.CAMERA_FACING_BACK);
|
||||||
mFocusOverlayManager.onPreviewStarted();
|
mFocusOverlayManager.onPreviewStarted();
|
||||||
@@ -830,24 +819,17 @@ class CameraManager implements FocusOverlayManager.Listener {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
mMediaRecorder.setOnErrorListener(new MediaRecorder.OnErrorListener() {
|
mMediaRecorder.setOnErrorListener((mediaRecorder, what, extra) -> {
|
||||||
@Override
|
if (mListener != null) {
|
||||||
public void onError(final MediaRecorder mediaRecorder, final int what,
|
mListener.onCameraError(ERROR_RECORDING_VIDEO, null);
|
||||||
final int extra) {
|
|
||||||
if (mListener != null) {
|
|
||||||
mListener.onCameraError(ERROR_RECORDING_VIDEO, null);
|
|
||||||
}
|
|
||||||
restoreRequestedOrientation();
|
|
||||||
}
|
}
|
||||||
|
restoreRequestedOrientation();
|
||||||
});
|
});
|
||||||
|
|
||||||
mMediaRecorder.setOnInfoListener(new MediaRecorder.OnInfoListener() {
|
mMediaRecorder.setOnInfoListener((mediaRecorder, what, extra) -> {
|
||||||
@Override
|
if (what == MediaRecorder.MEDIA_RECORDER_INFO_MAX_DURATION_REACHED ||
|
||||||
public void onInfo(final MediaRecorder mediaRecorder, final int what, final int extra) {
|
what == MediaRecorder.MEDIA_RECORDER_INFO_MAX_FILESIZE_REACHED) {
|
||||||
if (what == MediaRecorder.MEDIA_RECORDER_INFO_MAX_DURATION_REACHED ||
|
stopVideo();
|
||||||
what == MediaRecorder.MEDIA_RECORDER_INFO_MAX_FILESIZE_REACHED) {
|
|
||||||
stopVideo();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -1094,12 +1076,8 @@ class CameraManager implements FocusOverlayManager.Listener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
mCamera.autoFocus(new Camera.AutoFocusCallback() {
|
mCamera.autoFocus((success, camera) -> mFocusOverlayManager.onAutoFocus(success,
|
||||||
@Override
|
false /* shutterDown */));
|
||||||
public void onAutoFocus(final boolean success, final Camera camera) {
|
|
||||||
mFocusOverlayManager.onAutoFocus(success, false /* shutterDown */);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} catch (final RuntimeException e) {
|
} catch (final RuntimeException e) {
|
||||||
LogUtil.e(TAG, "RuntimeException in CameraManager.autoFocus", e);
|
LogUtil.e(TAG, "RuntimeException in CameraManager.autoFocus", e);
|
||||||
// If autofocus fails, the camera should have called the callback with success=false,
|
// If autofocus fails, the camera should have called the callback with success=false,
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2015 The Android Open Source Project
|
* Copyright (C) 2015 The Android Open Source Project
|
||||||
|
* Copyright (C) 2024 The LineageOS Project
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -24,7 +25,6 @@ import android.hardware.Camera;
|
|||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.SystemClock;
|
import android.os.SystemClock;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.MotionEvent;
|
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.view.animation.AlphaAnimation;
|
import android.view.animation.AlphaAnimation;
|
||||||
@@ -92,120 +92,98 @@ class CameraMediaChooser extends MediaChooser implements
|
|||||||
false /* attachToRoot */);
|
false /* attachToRoot */);
|
||||||
mCameraPreviewHost = (CameraPreview.CameraPreviewHost) view.findViewById(
|
mCameraPreviewHost = (CameraPreview.CameraPreviewHost) view.findViewById(
|
||||||
R.id.camera_preview);
|
R.id.camera_preview);
|
||||||
mCameraPreviewHost.getView().setOnTouchListener(new View.OnTouchListener() {
|
mCameraPreviewHost.getView().setOnTouchListener((view1, motionEvent) -> {
|
||||||
@Override
|
if (CameraManager.get().isVideoMode()) {
|
||||||
public boolean onTouch(final View view, final MotionEvent motionEvent) {
|
// Prevent the swipe down in video mode because video is always captured in
|
||||||
if (CameraManager.get().isVideoMode()) {
|
// full screen
|
||||||
// Prevent the swipe down in video mode because video is always captured in
|
return true;
|
||||||
// full screen
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
});
|
});
|
||||||
|
|
||||||
final View shutterVisual = view.findViewById(R.id.camera_shutter_visual);
|
final View shutterVisual = view.findViewById(R.id.camera_shutter_visual);
|
||||||
|
|
||||||
mFullScreenButton = (ImageButton) view.findViewById(R.id.camera_fullScreen_button);
|
mFullScreenButton = (ImageButton) view.findViewById(R.id.camera_fullScreen_button);
|
||||||
mFullScreenButton.setOnClickListener(new View.OnClickListener() {
|
mFullScreenButton.setOnClickListener(view12 -> mMediaPicker.setFullScreen(true));
|
||||||
@Override
|
|
||||||
public void onClick(final View view) {
|
|
||||||
mMediaPicker.setFullScreen(true);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
mSwapCameraButton = (ImageButton) view.findViewById(R.id.camera_swapCamera_button);
|
mSwapCameraButton = (ImageButton) view.findViewById(R.id.camera_swapCamera_button);
|
||||||
mSwapCameraButton.setOnClickListener(new View.OnClickListener() {
|
mSwapCameraButton.setOnClickListener(view13 -> CameraManager.get().swapCamera());
|
||||||
@Override
|
|
||||||
public void onClick(final View view) {
|
|
||||||
CameraManager.get().swapCamera();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
mCaptureButton = (ImageButton) view.findViewById(R.id.camera_capture_button);
|
mCaptureButton = (ImageButton) view.findViewById(R.id.camera_capture_button);
|
||||||
mCaptureButton.setOnClickListener(new View.OnClickListener() {
|
mCaptureButton.setOnClickListener(v -> {
|
||||||
@Override
|
final float heightPercent = Math.min(mMediaPicker.getViewPager().getHeight() /
|
||||||
public void onClick(final View v) {
|
(float) mCameraPreviewHost.getView().getHeight(), 1);
|
||||||
final float heightPercent = Math.min(mMediaPicker.getViewPager().getHeight() /
|
|
||||||
(float) mCameraPreviewHost.getView().getHeight(), 1);
|
|
||||||
|
|
||||||
if (CameraManager.get().isRecording()) {
|
if (CameraManager.get().isRecording()) {
|
||||||
CameraManager.get().stopVideo();
|
CameraManager.get().stopVideo();
|
||||||
} else {
|
} else {
|
||||||
final CameraManager.MediaCallback callback = new CameraManager.MediaCallback() {
|
final MediaCallback callback = new MediaCallback() {
|
||||||
@Override
|
@Override
|
||||||
public void onMediaReady(
|
public void onMediaReady(
|
||||||
final Uri uriToVideo, final String contentType,
|
final Uri uriToVideo, final String contentType,
|
||||||
final int width, final int height) {
|
final int width, final int height) {
|
||||||
mVideoCounter.stop();
|
mVideoCounter.stop();
|
||||||
if (mVideoCancelled || uriToVideo == null) {
|
if (mVideoCancelled || uriToVideo == null) {
|
||||||
mVideoCancelled = false;
|
mVideoCancelled = false;
|
||||||
} else {
|
} else {
|
||||||
final Rect startRect = new Rect();
|
final Rect startRect = new Rect();
|
||||||
// It's possible to throw out the chooser while taking the
|
// It's possible to throw out the chooser while taking the
|
||||||
// picture/video. In that case, still use the attachment, just
|
// picture/video. In that case, still use the attachment, just
|
||||||
// skip the startRect
|
// skip the startRect
|
||||||
if (mView != null) {
|
if (mView != null) {
|
||||||
mView.getGlobalVisibleRect(startRect);
|
mView.getGlobalVisibleRect(startRect);
|
||||||
}
|
|
||||||
mMediaPicker.dispatchItemsSelected(
|
|
||||||
new MediaPickerMessagePartData(startRect, contentType,
|
|
||||||
uriToVideo, width, height),
|
|
||||||
true /* dismissMediaPicker */);
|
|
||||||
}
|
}
|
||||||
updateViewState();
|
mMediaPicker.dispatchItemsSelected(
|
||||||
|
new MediaPickerMessagePartData(startRect, contentType,
|
||||||
|
uriToVideo, width, height),
|
||||||
|
true /* dismissMediaPicker */);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onMediaFailed(final Exception exception) {
|
|
||||||
UiUtils.showToastAtBottom(R.string.camera_media_failure);
|
|
||||||
updateViewState();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onMediaInfo(final int what) {
|
|
||||||
if (what == MediaCallback.MEDIA_NO_DATA) {
|
|
||||||
UiUtils.showToastAtBottom(R.string.camera_media_failure);
|
|
||||||
}
|
|
||||||
updateViewState();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
if (CameraManager.get().isVideoMode()) {
|
|
||||||
CameraManager.get().startVideo(callback);
|
|
||||||
mVideoCounter.setBase(SystemClock.elapsedRealtime());
|
|
||||||
mVideoCounter.start();
|
|
||||||
updateViewState();
|
|
||||||
} else {
|
|
||||||
showShutterEffect(shutterVisual);
|
|
||||||
CameraManager.get().takePicture(heightPercent, callback);
|
|
||||||
updateViewState();
|
updateViewState();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onMediaFailed(final Exception exception) {
|
||||||
|
UiUtils.showToastAtBottom(R.string.camera_media_failure);
|
||||||
|
updateViewState();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onMediaInfo(final int what) {
|
||||||
|
if (what == MediaCallback.MEDIA_NO_DATA) {
|
||||||
|
UiUtils.showToastAtBottom(R.string.camera_media_failure);
|
||||||
|
}
|
||||||
|
updateViewState();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
if (CameraManager.get().isVideoMode()) {
|
||||||
|
CameraManager.get().startVideo(callback);
|
||||||
|
mVideoCounter.setBase(SystemClock.elapsedRealtime());
|
||||||
|
mVideoCounter.start();
|
||||||
|
updateViewState();
|
||||||
|
} else {
|
||||||
|
showShutterEffect(shutterVisual);
|
||||||
|
CameraManager.get().takePicture(heightPercent, callback);
|
||||||
|
updateViewState();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
mSwapModeButton = (ImageButton) view.findViewById(R.id.camera_swap_mode_button);
|
mSwapModeButton = (ImageButton) view.findViewById(R.id.camera_swap_mode_button);
|
||||||
mSwapModeButton.setOnClickListener(new View.OnClickListener() {
|
mSwapModeButton.setOnClickListener(view14 -> {
|
||||||
@Override
|
final boolean isSwitchingToVideo = !CameraManager.get().isVideoMode();
|
||||||
public void onClick(final View view) {
|
if (isSwitchingToVideo && !OsUtil.hasRecordAudioPermission()) {
|
||||||
final boolean isSwitchingToVideo = !CameraManager.get().isVideoMode();
|
requestRecordAudioPermission();
|
||||||
if (isSwitchingToVideo && !OsUtil.hasRecordAudioPermission()) {
|
} else {
|
||||||
requestRecordAudioPermission();
|
onSwapMode();
|
||||||
} else {
|
|
||||||
onSwapMode();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
mCancelVideoButton = (ImageButton) view.findViewById(R.id.camera_cancel_button);
|
mCancelVideoButton = (ImageButton) view.findViewById(R.id.camera_cancel_button);
|
||||||
mCancelVideoButton.setOnClickListener(new View.OnClickListener() {
|
mCancelVideoButton.setOnClickListener(view15 -> {
|
||||||
@Override
|
mVideoCancelled = true;
|
||||||
public void onClick(final View view) {
|
CameraManager.get().stopVideo();
|
||||||
mVideoCancelled = true;
|
mMediaPicker.dismiss(true);
|
||||||
CameraManager.get().stopVideo();
|
|
||||||
mMediaPicker.dismiss(true);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
mVideoCounter = (Chronometer) view.findViewById(R.id.camera_video_counter);
|
mVideoCounter = (Chronometer) view.findViewById(R.id.camera_video_counter);
|
||||||
|
|||||||
@@ -83,23 +83,20 @@ public class CameraMediaChooserView extends FrameLayout implements PersistentIns
|
|||||||
if (!canvas.isHardwareAccelerated() && !mIsSoftwareFallbackActive) {
|
if (!canvas.isHardwareAccelerated() && !mIsSoftwareFallbackActive) {
|
||||||
mIsSoftwareFallbackActive = true;
|
mIsSoftwareFallbackActive = true;
|
||||||
// Post modifying the tree since we can't modify the view tree during a draw pass
|
// Post modifying the tree since we can't modify the view tree during a draw pass
|
||||||
ThreadUtil.getMainThreadHandler().post(new Runnable() {
|
ThreadUtil.getMainThreadHandler().post(() -> {
|
||||||
@Override
|
final HardwareCameraPreview cameraPreview =
|
||||||
public void run() {
|
(HardwareCameraPreview) findViewById(R.id.camera_preview);
|
||||||
final HardwareCameraPreview cameraPreview =
|
if (cameraPreview == null) {
|
||||||
(HardwareCameraPreview) findViewById(R.id.camera_preview);
|
return;
|
||||||
if (cameraPreview == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
final ViewGroup parent = ((ViewGroup) cameraPreview.getParent());
|
|
||||||
final int index = parent.indexOfChild(cameraPreview);
|
|
||||||
final SoftwareCameraPreview softwareCameraPreview =
|
|
||||||
new SoftwareCameraPreview(getContext());
|
|
||||||
// Be sure to remove the hardware view before adding the software view to
|
|
||||||
// prevent having 2 camera previews active at the same time
|
|
||||||
parent.removeView(cameraPreview);
|
|
||||||
parent.addView(softwareCameraPreview, index);
|
|
||||||
}
|
}
|
||||||
|
final ViewGroup parent = ((ViewGroup) cameraPreview.getParent());
|
||||||
|
final int index = parent.indexOfChild(cameraPreview);
|
||||||
|
final SoftwareCameraPreview softwareCameraPreview =
|
||||||
|
new SoftwareCameraPreview(getContext());
|
||||||
|
// Be sure to remove the hardware view before adding the software view to
|
||||||
|
// prevent having 2 camera previews active at the same time
|
||||||
|
parent.removeView(cameraPreview);
|
||||||
|
parent.addView(softwareCameraPreview, index);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2020 The Android Open Source Project
|
* Copyright (C) 2020 The Android Open Source Project
|
||||||
|
* Copyright (C) 2024 The LineageOS Project
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -77,14 +78,10 @@ class ContactMediaChooser extends MediaChooser {
|
|||||||
false /* attachToRoot */);
|
false /* attachToRoot */);
|
||||||
mEnabledView = view.findViewById(R.id.mediapicker_enabled);
|
mEnabledView = view.findViewById(R.id.mediapicker_enabled);
|
||||||
mMissingPermissionView = view.findViewById(R.id.missing_permission_view);
|
mMissingPermissionView = view.findViewById(R.id.missing_permission_view);
|
||||||
mEnabledView.setOnClickListener(
|
mEnabledView.setOnClickListener(v -> {
|
||||||
new View.OnClickListener() {
|
// Launch an external picker to pick a contact as attachment.
|
||||||
@Override
|
UIIntents.get().launchContactCardPicker(mMediaPicker);
|
||||||
public void onClick(final View v) {
|
});
|
||||||
// Launch an external picker to pick a contact as attachment.
|
|
||||||
UIIntents.get().launchContactCardPicker(mMediaPicker);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return view;
|
return view;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -128,14 +125,11 @@ class ContactMediaChooser extends MediaChooser {
|
|||||||
}
|
}
|
||||||
final Uri vCardUri = Uri.withAppendedPath(Contacts.CONTENT_VCARD_URI, lookupKey);
|
final Uri vCardUri = Uri.withAppendedPath(Contacts.CONTENT_VCARD_URI, lookupKey);
|
||||||
if (vCardUri != null) {
|
if (vCardUri != null) {
|
||||||
SafeAsyncTask.executeOnThreadPool(new Runnable() {
|
SafeAsyncTask.executeOnThreadPool(() -> {
|
||||||
@Override
|
final PendingAttachmentData pendingItem =
|
||||||
public void run() {
|
PendingAttachmentData.createPendingAttachmentData(
|
||||||
final PendingAttachmentData pendingItem =
|
ContentType.TEXT_X_VCARD.toLowerCase(), vCardUri);
|
||||||
PendingAttachmentData.createPendingAttachmentData(
|
mMediaPicker.dispatchPendingItemAdded(pendingItem);
|
||||||
ContentType.TEXT_X_VCARD.toLowerCase(), vCardUri);
|
|
||||||
mMediaPicker.dispatchPendingItemAdded(pendingItem);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -92,12 +92,9 @@ public class GalleryGridItemView extends FrameLayout {
|
|||||||
mFileName = (TextView) findViewById(R.id.file_name);
|
mFileName = (TextView) findViewById(R.id.file_name);
|
||||||
mFileType = (TextView) findViewById(R.id.file_type);
|
mFileType = (TextView) findViewById(R.id.file_type);
|
||||||
setOnClickListener(mOnClickListener);
|
setOnClickListener(mOnClickListener);
|
||||||
final OnLongClickListener longClickListener = new OnLongClickListener() {
|
final OnLongClickListener longClickListener = v -> {
|
||||||
@Override
|
mHostInterface.onItemClicked(v, mData, true /* longClick */);
|
||||||
public boolean onLongClick(final View v) {
|
return true;
|
||||||
mHostInterface.onItemClicked(v, mData, true /* longClick */);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
setOnLongClickListener(longClickListener);
|
setOnLongClickListener(longClickListener);
|
||||||
mCheckBox.setOnLongClickListener(longClickListener);
|
mCheckBox.setOnLongClickListener(longClickListener);
|
||||||
|
|||||||
@@ -38,9 +38,7 @@ import com.android.messaging.datamodel.data.GalleryGridItemData;
|
|||||||
import com.android.messaging.datamodel.data.MediaPickerData;
|
import com.android.messaging.datamodel.data.MediaPickerData;
|
||||||
import com.android.messaging.datamodel.data.MessagePartData;
|
import com.android.messaging.datamodel.data.MessagePartData;
|
||||||
import com.android.messaging.datamodel.data.MediaPickerData.MediaPickerDataListener;
|
import com.android.messaging.datamodel.data.MediaPickerData.MediaPickerDataListener;
|
||||||
import com.android.messaging.datamodel.data.PendingAttachmentData;
|
|
||||||
import com.android.messaging.ui.UIIntents;
|
import com.android.messaging.ui.UIIntents;
|
||||||
import com.android.messaging.ui.mediapicker.DocumentImagePicker.SelectionListener;
|
|
||||||
import com.android.messaging.util.Assert;
|
import com.android.messaging.util.Assert;
|
||||||
import com.android.messaging.util.OsUtil;
|
import com.android.messaging.util.OsUtil;
|
||||||
|
|
||||||
@@ -59,15 +57,11 @@ class GalleryMediaChooser extends MediaChooser implements
|
|||||||
GalleryMediaChooser(final MediaPicker mediaPicker) {
|
GalleryMediaChooser(final MediaPicker mediaPicker) {
|
||||||
super(mediaPicker);
|
super(mediaPicker);
|
||||||
mAdapter = new GalleryGridAdapter(Factory.get().getApplicationContext(), null);
|
mAdapter = new GalleryGridAdapter(Factory.get().getApplicationContext(), null);
|
||||||
mDocumentImagePicker = new DocumentImagePicker(mMediaPicker,
|
mDocumentImagePicker = new DocumentImagePicker(mMediaPicker, data -> {
|
||||||
new SelectionListener() {
|
if (mBindingRef.isBound()) {
|
||||||
@Override
|
mMediaPicker.dispatchPendingItemAdded(data);
|
||||||
public void onDocumentSelected(final PendingAttachmentData data) {
|
}
|
||||||
if (mBindingRef.isBound()) {
|
});
|
||||||
mMediaPicker.dispatchPendingItemAdded(data);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2015 The Android Open Source Project
|
* Copyright (C) 2015 The Android Open Source Project
|
||||||
|
* Copyright (C) 2024 The LineageOS Project
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -146,13 +147,9 @@ public class LevelTrackingMediaRecorder {
|
|||||||
"media recorder. " + ex);
|
"media recorder. " + ex);
|
||||||
if (mOutputUri != null) {
|
if (mOutputUri != null) {
|
||||||
final Uri outputUri = mOutputUri;
|
final Uri outputUri = mOutputUri;
|
||||||
SafeAsyncTask.executeOnThreadPool(new Runnable() {
|
SafeAsyncTask.executeOnThreadPool(() ->
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
Factory.get().getApplicationContext().getContentResolver().delete(
|
Factory.get().getApplicationContext().getContentResolver().delete(
|
||||||
outputUri, null, null);
|
outputUri, null, null));
|
||||||
}
|
|
||||||
});
|
|
||||||
mOutputUri = null;
|
mOutputUri = null;
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
@@ -191,26 +188,23 @@ public class LevelTrackingMediaRecorder {
|
|||||||
|
|
||||||
private void startTrackingSoundLevel() {
|
private void startTrackingSoundLevel() {
|
||||||
stopTrackingSoundLevel();
|
stopTrackingSoundLevel();
|
||||||
mRefreshLevelThread = new Thread() {
|
mRefreshLevelThread = new Thread(() -> {
|
||||||
@Override
|
try {
|
||||||
public void run() {
|
while (true) {
|
||||||
try {
|
synchronized (LevelTrackingMediaRecorder.class) {
|
||||||
while (true) {
|
if (mRecorder != null) {
|
||||||
synchronized (LevelTrackingMediaRecorder.class) {
|
mLevelSource.setSpeechLevel(getAmplitude());
|
||||||
if (mRecorder != null) {
|
} else {
|
||||||
mLevelSource.setSpeechLevel(getAmplitude());
|
// The recording session is over, finish the thread.
|
||||||
} else {
|
return;
|
||||||
// The recording session is over, finish the thread.
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
Thread.sleep(REFRESH_INTERVAL_MILLIS);
|
|
||||||
}
|
}
|
||||||
} catch (final InterruptedException e) {
|
Thread.sleep(REFRESH_INTERVAL_MILLIS);
|
||||||
Thread.currentThread().interrupt();
|
|
||||||
}
|
}
|
||||||
|
} catch (final InterruptedException e) {
|
||||||
|
Thread.currentThread().interrupt();
|
||||||
}
|
}
|
||||||
};
|
});
|
||||||
mRefreshLevelThread.start();
|
mRefreshLevelThread.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2015 The Android Open Source Project
|
* Copyright (C) 2015 The Android Open Source Project
|
||||||
|
* Copyright (C) 2024 The LineageOS Project
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -24,7 +25,6 @@ import android.view.LayoutInflater;
|
|||||||
import android.view.Menu;
|
import android.view.Menu;
|
||||||
import android.view.MenuInflater;
|
import android.view.MenuInflater;
|
||||||
import android.view.MenuItem;
|
import android.view.MenuItem;
|
||||||
import android.view.View;
|
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.widget.ImageButton;
|
import android.widget.ImageButton;
|
||||||
|
|
||||||
@@ -93,12 +93,7 @@ abstract class MediaChooser extends BasePagerViewHolder
|
|||||||
mTabButton.setContentDescription(
|
mTabButton.setContentDescription(
|
||||||
inflater.getContext().getResources().getString(getIconDescriptionResource()));
|
inflater.getContext().getResources().getString(getIconDescriptionResource()));
|
||||||
setSelected(mSelected);
|
setSelected(mSelected);
|
||||||
mTabButton.setOnClickListener(new View.OnClickListener() {
|
mTabButton.setOnClickListener(view -> mMediaPicker.selectChooser(MediaChooser.this));
|
||||||
@Override
|
|
||||||
public void onClick(final View view) {
|
|
||||||
mMediaPicker.selectChooser(MediaChooser.this);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Context getContext() {
|
protected Context getContext() {
|
||||||
|
|||||||
@@ -543,12 +543,7 @@ public class MediaPicker extends Fragment implements DraftMessageSubscriptionDat
|
|||||||
mOpen = true;
|
mOpen = true;
|
||||||
mPagerAdapter.notifyDataSetChanged();
|
mPagerAdapter.notifyDataSetChanged();
|
||||||
if (mListener != null) {
|
if (mListener != null) {
|
||||||
mListenerHandler.post(new Runnable() {
|
mListenerHandler.post(() -> mListener.onOpened());
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
mListener.onOpened();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
if (mSelectedChooser != null) {
|
if (mSelectedChooser != null) {
|
||||||
mSelectedChooser.onFullScreenChanged(false);
|
mSelectedChooser.onFullScreenChanged(false);
|
||||||
@@ -560,12 +555,7 @@ public class MediaPicker extends Fragment implements DraftMessageSubscriptionDat
|
|||||||
setHasOptionsMenu(false);
|
setHasOptionsMenu(false);
|
||||||
mOpen = false;
|
mOpen = false;
|
||||||
if (mListener != null) {
|
if (mListener != null) {
|
||||||
mListenerHandler.post(new Runnable() {
|
mListenerHandler.post(() -> mListener.onDismissed());
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
mListener.onDismissed();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
if (mSelectedChooser != null) {
|
if (mSelectedChooser != null) {
|
||||||
mSelectedChooser.onOpenedChanged(false);
|
mSelectedChooser.onOpenedChanged(false);
|
||||||
@@ -575,12 +565,7 @@ public class MediaPicker extends Fragment implements DraftMessageSubscriptionDat
|
|||||||
void dispatchFullScreen(final boolean fullScreen) {
|
void dispatchFullScreen(final boolean fullScreen) {
|
||||||
setHasOptionsMenu(fullScreen);
|
setHasOptionsMenu(fullScreen);
|
||||||
if (mListener != null) {
|
if (mListener != null) {
|
||||||
mListenerHandler.post(new Runnable() {
|
mListenerHandler.post(() -> mListener.onFullScreenChanged(fullScreen));
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
mListener.onFullScreenChanged(fullScreen);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
if (mSelectedChooser != null) {
|
if (mSelectedChooser != null) {
|
||||||
mSelectedChooser.onFullScreenChanged(fullScreen);
|
mSelectedChooser.onFullScreenChanged(fullScreen);
|
||||||
@@ -596,12 +581,7 @@ public class MediaPicker extends Fragment implements DraftMessageSubscriptionDat
|
|||||||
void dispatchItemsSelected(final Collection<MessagePartData> items,
|
void dispatchItemsSelected(final Collection<MessagePartData> items,
|
||||||
final boolean dismissMediaPicker) {
|
final boolean dismissMediaPicker) {
|
||||||
if (mListener != null) {
|
if (mListener != null) {
|
||||||
mListenerHandler.post(new Runnable() {
|
mListenerHandler.post(() -> mListener.onItemsSelected(items, dismissMediaPicker));
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
mListener.onItemsSelected(items, dismissMediaPicker);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isFullScreen() && !dismissMediaPicker) {
|
if (isFullScreen() && !dismissMediaPicker) {
|
||||||
@@ -611,12 +591,7 @@ public class MediaPicker extends Fragment implements DraftMessageSubscriptionDat
|
|||||||
|
|
||||||
void dispatchItemUnselected(final MessagePartData item) {
|
void dispatchItemUnselected(final MessagePartData item) {
|
||||||
if (mListener != null) {
|
if (mListener != null) {
|
||||||
mListenerHandler.post(new Runnable() {
|
mListenerHandler.post(() -> mListener.onItemUnselected(item));
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
mListener.onItemUnselected(item);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isFullScreen()) {
|
if (isFullScreen()) {
|
||||||
@@ -626,23 +601,13 @@ public class MediaPicker extends Fragment implements DraftMessageSubscriptionDat
|
|||||||
|
|
||||||
void dispatchConfirmItemSelection() {
|
void dispatchConfirmItemSelection() {
|
||||||
if (mListener != null) {
|
if (mListener != null) {
|
||||||
mListenerHandler.post(new Runnable() {
|
mListenerHandler.post(() -> mListener.onConfirmItemSelection());
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
mListener.onConfirmItemSelection();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void dispatchPendingItemAdded(final PendingAttachmentData pendingItem) {
|
void dispatchPendingItemAdded(final PendingAttachmentData pendingItem) {
|
||||||
if (mListener != null) {
|
if (mListener != null) {
|
||||||
mListenerHandler.post(new Runnable() {
|
mListenerHandler.post(() -> mListener.onPendingItemAdded(pendingItem));
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
mListener.onPendingItemAdded(pendingItem);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isFullScreen()) {
|
if (isFullScreen()) {
|
||||||
@@ -652,12 +617,7 @@ public class MediaPicker extends Fragment implements DraftMessageSubscriptionDat
|
|||||||
|
|
||||||
void dispatchChooserSelected(final int chooserIndex) {
|
void dispatchChooserSelected(final int chooserIndex) {
|
||||||
if (mListener != null) {
|
if (mListener != null) {
|
||||||
mListenerHandler.post(new Runnable() {
|
mListenerHandler.post(() -> mListener.onChooserSelected(chooserIndex));
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
mListener.onChooserSelected(chooserIndex);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2015 The Android Open Source Project
|
* Copyright (C) 2015 The Android Open Source Project
|
||||||
|
* Copyright (C) 2024 The LineageOS Project
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -250,12 +251,7 @@ public class MediaPickerPanel extends ViewGroup {
|
|||||||
}
|
}
|
||||||
mFullScreen = false;
|
mFullScreen = false;
|
||||||
mExpanded = expanded;
|
mExpanded = expanded;
|
||||||
mHandler.post(new Runnable() {
|
mHandler.post(() -> setDesiredHeight(getDesiredHeight(), animate));
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
setDesiredHeight(getDesiredHeight(), animate);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
if (expanded) {
|
if (expanded) {
|
||||||
setupViewPager(startingPage);
|
setupViewPager(startingPage);
|
||||||
mMediaPicker.dispatchOpened();
|
mMediaPicker.dispatchOpened();
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2015 The Android Open Source Project
|
* Copyright (C) 2015 The Android Open Source Project
|
||||||
|
* Copyright (C) 2024 The LineageOS Project
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -110,13 +111,9 @@ class MmsVideoRecorder extends MediaRecorder {
|
|||||||
|
|
||||||
void cleanupTempFile() {
|
void cleanupTempFile() {
|
||||||
final Uri tempUri = mTempVideoUri;
|
final Uri tempUri = mTempVideoUri;
|
||||||
SafeAsyncTask.executeOnThreadPool(new Runnable() {
|
SafeAsyncTask.executeOnThreadPool(() ->
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
Factory.get().getApplicationContext().getContentResolver().delete(
|
Factory.get().getApplicationContext().getContentResolver().delete(
|
||||||
tempUri, null, null);
|
tempUri, null, null));
|
||||||
}
|
|
||||||
});
|
|
||||||
mTempVideoUri = null;
|
mTempVideoUri = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -18,7 +18,6 @@ package com.android.messaging.ui.mediapicker;
|
|||||||
|
|
||||||
import android.animation.ObjectAnimator;
|
import android.animation.ObjectAnimator;
|
||||||
import android.animation.TimeAnimator;
|
import android.animation.TimeAnimator;
|
||||||
import android.animation.TimeAnimator.TimeListener;
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.res.TypedArray;
|
import android.content.res.TypedArray;
|
||||||
import android.graphics.Canvas;
|
import android.graphics.Canvas;
|
||||||
@@ -107,13 +106,7 @@ public class SoundLevels extends View {
|
|||||||
// which might improve things further.
|
// which might improve things further.
|
||||||
mSpeechLevelsAnimator = new TimeAnimator();
|
mSpeechLevelsAnimator = new TimeAnimator();
|
||||||
mSpeechLevelsAnimator.setRepeatCount(ObjectAnimator.INFINITE);
|
mSpeechLevelsAnimator.setRepeatCount(ObjectAnimator.INFINITE);
|
||||||
mSpeechLevelsAnimator.setTimeListener(new TimeListener() {
|
mSpeechLevelsAnimator.setTimeListener((animation, totalTime, deltaTime) -> invalidate());
|
||||||
@Override
|
|
||||||
public void onTimeUpdate(final TimeAnimator animation, final long totalTime,
|
|
||||||
final long deltaTime) {
|
|
||||||
invalidate();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -57,12 +57,7 @@ public final class Assert {
|
|||||||
|
|
||||||
// This is called from FactoryImpl once the Gservices class is initialized.
|
// This is called from FactoryImpl once the Gservices class is initialized.
|
||||||
public static void initializeGservices (final BugleGservices gservices) {
|
public static void initializeGservices (final BugleGservices gservices) {
|
||||||
gservices.registerForChanges(new Runnable() {
|
gservices.registerForChanges(() -> refreshGservices(gservices));
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
refreshGservices(gservices);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
refreshGservices(gservices);
|
refreshGservices(gservices);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2015 The Android Open Source Project
|
* Copyright (C) 2015 The Android Open Source Project
|
||||||
|
* Copyright (C) 2024 The LineageOS Project
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -20,7 +21,6 @@ import android.app.Activity;
|
|||||||
import android.app.AlertDialog;
|
import android.app.AlertDialog;
|
||||||
import android.app.Dialog;
|
import android.app.Dialog;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.DialogInterface;
|
|
||||||
import android.os.UserManager;
|
import android.os.UserManager;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
|
|
||||||
@@ -68,13 +68,7 @@ public class BugleActivityUtil {
|
|||||||
.setMessage(R.string.requires_sms_permissions_message)
|
.setMessage(R.string.requires_sms_permissions_message)
|
||||||
.setCancelable(false)
|
.setCancelable(false)
|
||||||
.setNegativeButton(R.string.requires_sms_permissions_close_button,
|
.setNegativeButton(R.string.requires_sms_permissions_close_button,
|
||||||
new DialogInterface.OnClickListener() {
|
(dialog, button) -> System.exit(0))
|
||||||
@Override
|
|
||||||
public void onClick(final DialogInterface dialog,
|
|
||||||
final int button) {
|
|
||||||
System.exit(0);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.show();
|
.show();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,7 +22,6 @@ import android.app.AlertDialog;
|
|||||||
import android.app.FragmentManager;
|
import android.app.FragmentManager;
|
||||||
import android.app.FragmentTransaction;
|
import android.app.FragmentTransaction;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.DialogInterface;
|
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.media.MediaPlayer;
|
import android.media.MediaPlayer;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
@@ -50,7 +49,6 @@ import java.io.File;
|
|||||||
import java.io.FileInputStream;
|
import java.io.FileInputStream;
|
||||||
import java.io.FileNotFoundException;
|
import java.io.FileNotFoundException;
|
||||||
import java.io.FileOutputStream;
|
import java.io.FileOutputStream;
|
||||||
import java.io.FilenameFilter;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.StreamCorruptedException;
|
import java.io.StreamCorruptedException;
|
||||||
|
|
||||||
@@ -193,13 +191,7 @@ public class DebugUtils {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
builder.setAdapter(arrayAdapter,
|
builder.setAdapter(arrayAdapter, (arg0, pos) -> arrayAdapter.getItem(pos).run());
|
||||||
new android.content.DialogInterface.OnClickListener() {
|
|
||||||
@Override
|
|
||||||
public void onClick(final DialogInterface arg0, final int pos) {
|
|
||||||
arrayAdapter.getItem(pos).run();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
builder.create().show();
|
builder.create().show();
|
||||||
}
|
}
|
||||||
@@ -231,16 +223,11 @@ public class DebugUtils {
|
|||||||
@Override
|
@Override
|
||||||
protected String[] doInBackgroundTimed(final Void... params) {
|
protected String[] doInBackgroundTimed(final Void... params) {
|
||||||
final File dir = DebugUtils.getDebugFilesDir();
|
final File dir = DebugUtils.getDebugFilesDir();
|
||||||
return dir.list(new FilenameFilter() {
|
return dir.list((dir1, filename) -> filename != null
|
||||||
@Override
|
&& ((mAction == DebugSmsMmsFromDumpFileDialogFragment.ACTION_EMAIL
|
||||||
public boolean accept(final File dir, final String filename) {
|
&& filename.equals(DumpDatabaseAction.DUMP_NAME))
|
||||||
return filename != null
|
|| filename.startsWith(MmsUtils.MMS_DUMP_PREFIX)
|
||||||
&& ((mAction == DebugSmsMmsFromDumpFileDialogFragment.ACTION_EMAIL
|
|| filename.startsWith(MmsUtils.SMS_DUMP_PREFIX)));
|
||||||
&& filename.equals(DumpDatabaseAction.DUMP_NAME))
|
|
||||||
|| filename.startsWith(MmsUtils.MMS_DUMP_PREFIX)
|
|
||||||
|| filename.startsWith(MmsUtils.SMS_DUMP_PREFIX));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2015 The Android Open Source Project
|
* Copyright (C) 2015 The Android Open Source Project
|
||||||
|
* Copyright (C) 2024 The LineageOS Project
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -58,12 +59,7 @@ public class LogUtil {
|
|||||||
|
|
||||||
// This is called from FactoryImpl once the Gservices class is initialized.
|
// This is called from FactoryImpl once the Gservices class is initialized.
|
||||||
public static void initializeGservices (final BugleGservices gservices) {
|
public static void initializeGservices (final BugleGservices gservices) {
|
||||||
gservices.registerForChanges(new Runnable() {
|
gservices.registerForChanges(() -> refreshGservices(gservices));
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
refreshGservices(gservices);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
refreshGservices(gservices);
|
refreshGservices(gservices);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2015 The Android Open Source Project
|
* Copyright (C) 2015 The Android Open Source Project
|
||||||
|
* Copyright (C) 2024 The LineageOS Project
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -42,15 +43,12 @@ public class MediaUtilImpl extends MediaUtil {
|
|||||||
afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength());
|
afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength());
|
||||||
afd.close();
|
afd.close();
|
||||||
mediaPlayer.prepare();
|
mediaPlayer.prepare();
|
||||||
mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
|
mediaPlayer.setOnCompletionListener(mp -> {
|
||||||
@Override
|
if (completionListener != null) {
|
||||||
public void onCompletion(final MediaPlayer mp) {
|
completionListener.onCompletion();
|
||||||
if (completionListener != null) {
|
|
||||||
completionListener.onCompletion();
|
|
||||||
}
|
|
||||||
mp.stop();
|
|
||||||
mp.release();
|
|
||||||
}
|
}
|
||||||
|
mp.stop();
|
||||||
|
mp.release();
|
||||||
});
|
});
|
||||||
mediaPlayer.seekTo(0);
|
mediaPlayer.seekTo(0);
|
||||||
mediaPlayer.start();
|
mediaPlayer.start();
|
||||||
@@ -63,4 +61,4 @@ public class MediaUtilImpl extends MediaUtil {
|
|||||||
completionListener.onCompletion();
|
completionListener.onCompletion();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -96,15 +96,12 @@ public abstract class SafeAsyncTask<Params, Progress, Result>
|
|||||||
Assert.isTrue(mThreadPoolRequested);
|
Assert.isTrue(mThreadPoolRequested);
|
||||||
|
|
||||||
if (mCancelExecutionOnTimeout) {
|
if (mCancelExecutionOnTimeout) {
|
||||||
ThreadUtil.getMainThreadHandler().postDelayed(new Runnable() {
|
ThreadUtil.getMainThreadHandler().postDelayed(() -> {
|
||||||
@Override
|
if (getStatus() == Status.RUNNING) {
|
||||||
public void run() {
|
// Cancel the task if it's still running.
|
||||||
if (getStatus() == Status.RUNNING) {
|
LogUtil.w(LogUtil.BUGLE_TAG, String.format("%s timed out and is canceled",
|
||||||
// Cancel the task if it's still running.
|
this));
|
||||||
LogUtil.w(LogUtil.BUGLE_TAG, String.format("%s timed out and is canceled",
|
cancel(true /* mayInterruptIfRunning */);
|
||||||
this));
|
|
||||||
cancel(true /* mayInterruptIfRunning */);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}, mMaxExecutionTimeMillis);
|
}, mMaxExecutionTimeMillis);
|
||||||
}
|
}
|
||||||
@@ -160,14 +157,11 @@ public abstract class SafeAsyncTask<Params, Progress, Result>
|
|||||||
if (withWakeLock) {
|
if (withWakeLock) {
|
||||||
final Intent intent = new Intent();
|
final Intent intent = new Intent();
|
||||||
sWakeLock.acquire(Factory.get().getApplicationContext(), intent, WAKELOCK_OP);
|
sWakeLock.acquire(Factory.get().getApplicationContext(), intent, WAKELOCK_OP);
|
||||||
THREAD_POOL_EXECUTOR.execute(new Runnable() {
|
THREAD_POOL_EXECUTOR.execute(() -> {
|
||||||
@Override
|
try {
|
||||||
public void run() {
|
runnable.run();
|
||||||
try {
|
} finally {
|
||||||
runnable.run();
|
sWakeLock.release(intent, WAKELOCK_OP);
|
||||||
} finally {
|
|
||||||
sWakeLock.release(intent, WAKELOCK_OP);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2015 The Android Open Source Project
|
* Copyright (C) 2015 The Android Open Source Project
|
||||||
|
* Copyright (C) 2024 The LineageOS Project
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -42,12 +43,7 @@ public class BugleWidgetProvider extends BaseWidgetProvider {
|
|||||||
@Override
|
@Override
|
||||||
protected void updateWidget(final Context context, final int appWidgetId) {
|
protected void updateWidget(final Context context, final int appWidgetId) {
|
||||||
if (OsUtil.hasRequiredPermissions()) {
|
if (OsUtil.hasRequiredPermissions()) {
|
||||||
SafeAsyncTask.executeOnThreadPool(new Runnable() {
|
SafeAsyncTask.executeOnThreadPool(() -> rebuildWidget(context, appWidgetId));
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
rebuildWidget(context, appWidgetId);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} else {
|
} else {
|
||||||
AppWidgetManager.getInstance(context).updateAppWidget(appWidgetId,
|
AppWidgetManager.getInstance(context).updateAppWidget(appWidgetId,
|
||||||
UiUtils.getWidgetMissingPermissionView(context));
|
UiUtils.getWidgetMissingPermissionView(context));
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2015 The Android Open Source Project
|
* Copyright (C) 2015 The Android Open Source Project
|
||||||
|
* Copyright (C) 2024 The LineageOS Project
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -148,12 +149,7 @@ public class WidgetConversationProvider extends BaseWidgetProvider {
|
|||||||
// widget dependent on ConversationListItemData. However, we have to update
|
// widget dependent on ConversationListItemData. However, we have to update
|
||||||
// the widget regardless, even with those missing pieces. Here we update the
|
// the widget regardless, even with those missing pieces. Here we update the
|
||||||
// widget again in the background.
|
// widget again in the background.
|
||||||
SafeAsyncTask.executeOnThreadPool(new Runnable() {
|
SafeAsyncTask.executeOnThreadPool(() -> rebuildWidget(context, appWidgetId));
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
rebuildWidget(context, appWidgetId);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user