Messaging: Looply home UI and Gradle app module layout
Restructure the tree for Android Studio/Gradle builds and add the iOS-style home experience with pinned conversations, selection chrome, and scroll-aware search padding. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,178 @@
|
||||
/*
|
||||
* Copyright (C) 2015 The Android Open Source Project
|
||||
* Copyright (C) 2024-2025 The LineageOS Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.messaging;
|
||||
|
||||
import android.app.Application;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.content.res.Configuration;
|
||||
import android.os.Handler;
|
||||
import android.support.v7.mms.CarrierConfigValuesLoader;
|
||||
import android.support.v7.mms.MmsManager;
|
||||
import android.telephony.CarrierConfigManager;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.android.messaging.datamodel.DataModel;
|
||||
import com.android.messaging.receiver.SmsReceiver;
|
||||
import com.android.messaging.sms.BugleApnSettingsLoader;
|
||||
import com.android.messaging.sms.BugleUserAgentInfoLoader;
|
||||
import com.android.messaging.sms.MmsConfig;
|
||||
import com.android.messaging.ui.ConversationDrawables;
|
||||
import com.android.messaging.util.BuglePrefsKeys;
|
||||
import com.android.messaging.util.LogUtil;
|
||||
import com.android.messaging.util.PhoneUtils;
|
||||
import com.android.messaging.util.Trace;
|
||||
|
||||
import java.lang.Thread.UncaughtExceptionHandler;
|
||||
|
||||
/**
|
||||
* The application object
|
||||
*/
|
||||
public class BugleApplication extends Application implements UncaughtExceptionHandler {
|
||||
private static final String TAG = LogUtil.BUGLE_TAG;
|
||||
|
||||
private UncaughtExceptionHandler sSystemUncaughtExceptionHandler;
|
||||
|
||||
@Override
|
||||
public void onCreate() {
|
||||
Trace.beginSection("app.onCreate");
|
||||
super.onCreate();
|
||||
|
||||
FactoryImpl.register(getApplicationContext(), this);
|
||||
|
||||
sSystemUncaughtExceptionHandler = Thread.getDefaultUncaughtExceptionHandler();
|
||||
Thread.setDefaultUncaughtExceptionHandler(this);
|
||||
Trace.endSection();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onConfigurationChanged(@NonNull final Configuration newConfig) {
|
||||
super.onConfigurationChanged(newConfig);
|
||||
|
||||
// Update conversation drawables when changing writing systems
|
||||
// (Right-To-Left / Left-To-Right)
|
||||
ConversationDrawables.get().updateDrawables();
|
||||
}
|
||||
|
||||
// Called by the "real" factory from FactoryImpl.register() (i.e. not run in tests)
|
||||
public void initializeSync(final Factory factory) {
|
||||
Trace.beginSection("app.initializeSync");
|
||||
final Context context = factory.getApplicationContext();
|
||||
final DataModel dataModel = factory.getDataModel();
|
||||
final CarrierConfigValuesLoader carrierConfigValuesLoader =
|
||||
factory.getCarrierConfigValuesLoader();
|
||||
|
||||
BugleApplication.updateAppConfig(context);
|
||||
|
||||
// Initialize MMS lib
|
||||
initMmsLib(context, carrierConfigValuesLoader);
|
||||
// Fixup messages in flight if we crashed and send any pending
|
||||
dataModel.onApplicationCreated();
|
||||
// Register carrier config change receiver
|
||||
registerCarrierConfigChangeReceiver(context);
|
||||
|
||||
Trace.endSection();
|
||||
}
|
||||
|
||||
private static void registerCarrierConfigChangeReceiver(final Context context) {
|
||||
context.registerReceiver(new BroadcastReceiver() {
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
LogUtil.i(TAG, "Carrier config changed. Reloading MMS config.");
|
||||
MmsConfig.loadAsync();
|
||||
}
|
||||
}, new IntentFilter(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED),
|
||||
Context.RECEIVER_EXPORTED/*UNAUDITED*/);
|
||||
}
|
||||
|
||||
private static void initMmsLib(final Context context,
|
||||
final CarrierConfigValuesLoader carrierConfigValuesLoader) {
|
||||
MmsManager.setApnSettingsLoader(new BugleApnSettingsLoader(context));
|
||||
MmsManager.setCarrierConfigValuesLoader(carrierConfigValuesLoader);
|
||||
MmsManager.setUserAgentInfoLoader(new BugleUserAgentInfoLoader(context));
|
||||
}
|
||||
|
||||
public static void updateAppConfig(final Context context) {
|
||||
// Make sure we set the correct state for the SMS/MMS receivers
|
||||
SmsReceiver.updateSmsReceiveHandler(context);
|
||||
}
|
||||
|
||||
// Called from thread started in FactoryImpl.register() (i.e. not run in tests)
|
||||
public void initializeAsync(final Factory factory) {
|
||||
// Handle shared prefs upgrade & Load MMS Configuration
|
||||
Trace.beginSection("app.initializeAsync");
|
||||
maybeHandleSharedPrefsUpgrade(factory);
|
||||
MmsConfig.load();
|
||||
Trace.endSection();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLowMemory() {
|
||||
super.onLowMemory();
|
||||
|
||||
if (LogUtil.isLoggable(TAG, LogUtil.DEBUG)) {
|
||||
LogUtil.d(TAG, "BugleApplication.onLowMemory");
|
||||
}
|
||||
Factory.get().reclaimMemory();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void uncaughtException(@NonNull final Thread thread, @NonNull final Throwable ex) {
|
||||
final boolean background = getMainLooper().getThread() != thread;
|
||||
if (background) {
|
||||
LogUtil.e(TAG, "Uncaught exception in background thread " + thread, ex);
|
||||
|
||||
final Handler handler = new Handler(getMainLooper());
|
||||
handler.post(() -> sSystemUncaughtExceptionHandler.uncaughtException(thread, ex));
|
||||
} else {
|
||||
sSystemUncaughtExceptionHandler.uncaughtException(thread, ex);
|
||||
}
|
||||
}
|
||||
|
||||
private void maybeHandleSharedPrefsUpgrade(final Factory factory) {
|
||||
final int existingVersion = factory.getApplicationPrefs().getInt(
|
||||
BuglePrefsKeys.SHARED_PREFERENCES_VERSION,
|
||||
BuglePrefsKeys.SHARED_PREFERENCES_VERSION_DEFAULT);
|
||||
final int targetVersion = Integer.parseInt(getString(R.string.pref_version));
|
||||
if (targetVersion > existingVersion) {
|
||||
LogUtil.i(LogUtil.BUGLE_TAG, "Upgrading shared prefs from " + existingVersion +
|
||||
" to " + targetVersion);
|
||||
try {
|
||||
// Perform upgrade on application-wide prefs.
|
||||
factory.getApplicationPrefs().onUpgrade(existingVersion, targetVersion);
|
||||
// Perform upgrade on each subscription's prefs.
|
||||
PhoneUtils.forEachActiveSubscription(subId -> factory.getSubscriptionPrefs(subId)
|
||||
.onUpgrade(existingVersion, targetVersion));
|
||||
factory.getApplicationPrefs().putInt(BuglePrefsKeys.SHARED_PREFERENCES_VERSION,
|
||||
targetVersion);
|
||||
} catch (final Exception ex) {
|
||||
// Upgrade failed. Don't crash the app because we can always fall back to the
|
||||
// default settings.
|
||||
LogUtil.e(LogUtil.BUGLE_TAG, "Failed to upgrade shared prefs", ex);
|
||||
}
|
||||
} else if (targetVersion < existingVersion) {
|
||||
// We don't care about downgrade since real user shouldn't encounter this, so log it
|
||||
// and ignore any prefs migration.
|
||||
LogUtil.e(LogUtil.BUGLE_TAG, "Shared prefs downgrade requested and ignored. " +
|
||||
"oldVersion = " + existingVersion + ", newVersion = " + targetVersion);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user