Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b28c4cab authored by Dirk Sigurdson's avatar Dirk Sigurdson
Browse files

Merge commit 'themes/themes-eclair' into themes-2.2_r1

Conflicts:

	api/current.xml
	core/java/android/app/ActivityManager.java
	core/java/android/app/ActivityThread.java
	core/java/android/app/ApplicationContext.java
	core/java/android/content/Intent.java
	core/java/android/content/pm/PackageInfo.java
	core/java/android/content/res/AssetManager.java
	core/java/android/content/res/Configuration.java
	core/jni/android_util_AssetManager.cpp
	media/java/android/media/Ringtone.java
	services/java/com/android/server/PackageManagerService.java
	services/java/com/android/server/am/ActivityManagerService.java
	test-runner/android/test/mock/MockPackageManager.java
parents 71beeab1 6d0e558b
Loading
Loading
Loading
Loading
+25 −0
Original line number Diff line number Diff line
@@ -148883,6 +148883,17 @@
<parameter name="flags" type="int">
</parameter>
</method>
<method name="getInstalledThemePackages"
 return="java.util.List&lt;android.content.pm.PackageInfo&gt;"
 abstract="false"
 native="false"
 synchronized="false"
 static="false"
 final="false"
 deprecated="not deprecated"
 visibility="public"
>
</method>
<method name="getInstallerPackageName"
 return="java.lang.String"
 abstract="false"
@@ -203359,6 +203370,20 @@
<parameter name="attrs" type="android.util.AttributeSet">
</parameter>
</constructor>
<constructor name="LinearLayout"
 type="android.widget.LinearLayout"
 static="false"
 final="false"
 deprecated="not deprecated"
 visibility="public"
>
<parameter name="context" type="android.content.Context">
</parameter>
<parameter name="attrs" type="android.util.AttributeSet">
</parameter>
<parameter name="defStyle" type="int">
</parameter>
</constructor>
<method name="getBaselineAlignedChildIndex"
 return="int"
 abstract="false"
+25 −0
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@ import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.ConfigurationInfo;
import android.content.pm.IPackageDataObserver;
import android.content.res.Configuration;
import android.graphics.Bitmap;
import android.os.Debug;
import android.os.RemoteException;
@@ -992,4 +993,28 @@ public class ActivityManager {
        }
        return false;
    }

    /**
     * @hide
     */
    public Configuration getConfiguration() {
        try {
            return ActivityManagerNative.getDefault().getConfiguration();
        } catch (RemoteException e) {
            return null;
        }
    }

    /**
     * @throws SecurityException Throws SecurityException if the caller does
     * not hold the {@link android.Manifest.permission#CHANGE_CONFIGURATION} permission.
     *
     * @hide
     */
    public void updateConfiguration(Configuration values) throws SecurityException {
        try {
            ActivityManagerNative.getDefault().updateConfiguration(values);
        } catch (RemoteException e) {
        }
    }
}
+135 −22
Original line number Diff line number Diff line
@@ -17,14 +17,24 @@
package android.app;

import android.app.backup.BackupAgent;
import com.android.internal.os.BinderInternal;
import com.android.internal.os.RuntimeInit;
import com.android.internal.os.SamplingProfilerIntegration;
import com.android.internal.util.ArrayUtils;

import dalvik.system.SamplingProfiler;

import org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl;

import android.content.BroadcastReceiver;
import android.content.ComponentCallbacks;
import android.content.ComponentName;
import android.content.ContentProvider;
import android.content.Context;
import android.content.ContextWrapper;
import android.content.IContentProvider;
import android.content.Intent;
import android.content.IIntentReceiver;
import android.content.Intent;
import android.content.ServiceConnection;
import android.content.pm.ActivityInfo;
import android.content.pm.ApplicationInfo;
@@ -36,12 +46,14 @@ import android.content.pm.ServiceInfo;
import android.content.res.AssetManager;
import android.content.res.CompatibilityInfo;
import android.content.res.Configuration;
import android.content.res.CustomTheme;
import android.content.res.Resources;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteDebug;
import android.database.sqlite.SQLiteDebug.DbStats;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.net.Uri;
import android.os.Bundle;
import android.os.Debug;
import android.os.Handler;
@@ -54,6 +66,7 @@ import android.os.Process;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.SystemClock;
import android.text.TextUtils;
import android.util.AndroidRuntimeException;
import android.util.Config;
import android.util.DisplayMetrics;
@@ -61,6 +74,7 @@ import android.util.EventLog;
import android.util.Log;
import android.util.Slog;
import android.view.Display;
import android.view.InflateException;
import android.view.View;
import android.view.ViewDebug;
import android.view.ViewManager;
@@ -69,13 +83,6 @@ import android.view.Window;
import android.view.WindowManager;
import android.view.WindowManagerImpl;

import com.android.internal.os.BinderInternal;
import com.android.internal.os.RuntimeInit;
import com.android.internal.os.SamplingProfilerIntegration;
import com.android.internal.util.ArrayUtils;

import org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl;

import java.io.File;
import java.io.FileDescriptor;
import java.io.FileOutputStream;
@@ -94,8 +101,6 @@ import java.util.Map;
import java.util.TimeZone;
import java.util.regex.Pattern;

import dalvik.system.SamplingProfiler;

final class IntentReceiverLeaked extends AndroidRuntimeException {
    public IntentReceiverLeaked(String msg) {
        super(msg);
@@ -182,8 +187,14 @@ public final class ActivityThread {
     * @param resDir the resource directory.
     * @param compInfo the compability info. It will use the default compatibility info when it's
     * null.
     * 
     * @deprecated use {@link #getTopLevelResources(String, CompatibilityInfo, boolean)} instead.
     */
    Resources getTopLevelResources(String resDir, CompatibilityInfo compInfo) {
        return getTopLevelResources(resDir, compInfo, false);
    }
    
    Resources getTopLevelResources(String resDir, CompatibilityInfo compInfo, boolean isThemable) {
        ResourcesKey key = new ResourcesKey(resDir, compInfo.applicationScale);
        Resources r;
        synchronized (mPackages) {
@@ -210,9 +221,28 @@ public final class ActivityThread {
        //}

        AssetManager assets = new AssetManager();
        assets.setThemeSupport(isThemable);
        if (assets.addAssetPath(resDir) == 0) {
            return null;
        }
        Configuration config = getConfiguration();
        if (isThemable && config != null) {
            if (config.customTheme == null) {
                config.customTheme = CustomTheme.getDefault();
            }

            if (!TextUtils.isEmpty(config.customTheme.getThemePackageName())) {
                PackageInfo pi = getPackageInfo(config.customTheme.getThemePackageName(), 0);
                if (pi != null) {
                    String themeResDir = pi.getResDir();
                    if (assets.addAssetPath(themeResDir) != 0) {
                        assets.setThemePackageName(config.customTheme.getThemePackageName());
                    } else {
                        Log.e(TAG, "Unable to add theme resdir=" + themeResDir);
                    }
                }
            }
        }

        //Slog.i(TAG, "Resource: key=" + key + ", display metrics=" + metrics);
        DisplayMetrics metrics = getDisplayMetricsLocked(false);
@@ -241,11 +271,17 @@ public final class ActivityThread {

    /**
     * Creates the top level resources for the given package.
     * 
     * @deprecated {@link #getTopLevelResources(String, PackageInfo, boolean)}
     */
    Resources getTopLevelResources(String resDir, PackageInfo pkgInfo) {
        return getTopLevelResources(resDir, pkgInfo.mCompatibilityInfo);
    }

    Resources getTopLevelResources(String resDir, PackageInfo pkgInfo, boolean themeable) {
        return getTopLevelResources(resDir, pkgInfo.mCompatibilityInfo, themeable);
    }

    final Handler getHandler() {
        return mH;
    }
@@ -253,7 +289,7 @@ public final class ActivityThread {
    public final static class PackageInfo {

        private final ActivityThread mActivityThread;
        private final ApplicationInfo mApplicationInfo;
        /* package */ final ApplicationInfo mApplicationInfo;
        private final String mPackageName;
        private final String mAppDir;
        private final String mResDir;
@@ -617,13 +653,19 @@ public final class ActivityThread {
            return getResources(mainThread).getAssets();
        }
        
        public Resources getResources(ActivityThread mainThread) {
            if (mResources == null) {
                mResources = mainThread.getTopLevelResources(mResDir, this);
        public Resources getResources(ActivityThread mainThread, boolean themeable,
                boolean force) {
            if (mResources == null || force == true) {
                mResources = mainThread.getTopLevelResources(mResDir, this, themeable);
            }
            return mResources;            
        }
        
        /** @deprecated use {@link #getResources(ActivityThread, boolean, boolean)} instead. */
        public Resources getResources(ActivityThread mainThread) {
            return getResources(mainThread, false, false);
        }

        public Application makeApplication(boolean forceDefaultAppClass,
                Instrumentation instrumentation) {
            if (mApplication != null) {
@@ -2660,6 +2702,16 @@ public final class ActivityThread {

        } catch (Exception e) {
            if (!mInstrumentation.onException(activity, e)) {
                if (e instanceof InflateException) {
                    Log.e(TAG, "Failed to inflate", e);
                    String pkg = null;
                    if (r.packageInfo != null && !TextUtils.isEmpty(r.packageInfo.getPackageName())) {
                        pkg = r.packageInfo.getPackageName();
                    }
                    Intent intent = new Intent(Intent.ACTION_APP_LAUNCH_FAILURE,
                            (pkg != null)? Uri.fromParts("package", pkg, null) : null);
                    getSystemContext().sendBroadcast(intent);
                }
                throw new RuntimeException(
                    "Unable to start activity " + component
                    + ": " + e.toString(), e);
@@ -3935,14 +3987,20 @@ public final class ActivityThread {
        }
    }

    final boolean applyConfigurationToResourcesLocked(Configuration config) {
    /*
     * Original code returned a boolean here to denote whether changes were
     * detected.  But T-Mobile must know what specifically has changed to check
     * later if the theme had changed, so we return the changes bitmap instead.
     * Caller beware.
     */
    final int applyConfigurationToResourcesLocked(Configuration config) {
        if (mResConfiguration == null) {
            mResConfiguration = new Configuration();
        }
        if (!mResConfiguration.isOtherSeqNewer(config)) {
            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Skipping new config: curSeq="
                    + mResConfiguration.seq + ", newSeq=" + config.seq);
            return false;
            return 0;
        }
        int changes = mResConfiguration.updateFrom(config);
        DisplayMetrics dm = getDisplayMetricsLocked(true);
@@ -3967,7 +4025,34 @@ public final class ActivityThread {
            if (r != null) {
                if (DEBUG_CONFIGURATION) Slog.v(TAG, "Changing resources "
                        + r + " config to: " + config);
                boolean themeChanged = (changes & ActivityInfo.CONFIG_THEME_RESOURCE) != 0;
                if (themeChanged) {
                    AssetManager am = r.getAssets();
                    /*
                     * Dynamically modify the AssetManager object to
                     * replace the old asset path with the new one. This
                     * is made possibly by native layer changes made by
                     * T-Mobile.
                     */
                    if (am.hasThemeSupport()) {
                        String oldThemePackage = am.getThemePackageName();
                        if (!TextUtils.isEmpty(oldThemePackage)) {
                            am.setThemePackageName(null);
                            am.removeAssetPath(oldThemePackage,
                                    getPackageResDir(oldThemePackage));
                        }
                        String newThemePackage = config.customTheme.getThemePackageName();
                        String resDir = getPackageResDir(newThemePackage);
                        if (resDir != null) {
                            am.setThemePackageName(newThemePackage);
                            am.updateResourcesWithAssetPath(resDir);
                        }
                    }
                }
                r.updateConfiguration(config, dm);
                if (themeChanged) {
                    r.updateStringCache();
                }
                //Slog.i(TAG, "Updated app resources " + v.getKey()
                //        + " " + r + ": " + r.getConfiguration());
            } else {
@@ -3976,13 +4061,28 @@ public final class ActivityThread {
            }
        }
        
        return changes != 0;
        return changes;
    }
    
    private String getPackageResDir(String packageName) {
        android.content.pm.PackageInfo pi;
        try {
            pi = getPackageManager().getPackageInfo(packageName, 0);
            if (pi == null || pi.applicationInfo == null)
                return null;
            return pi.applicationInfo.publicSourceDir;
        } catch (RemoteException e) {
            Log.e("ActivityThread", "Exception in getPackageResDir", e);
        }
        return null;
    }

    final void handleConfigurationChanged(Configuration config) {

        ArrayList<ComponentCallbacks> callbacks = null;

        int diff = 0;

        synchronized (mPackages) {
            if (mPendingConfiguration != null) {
                if (!mPendingConfiguration.isOtherSeqNewer(config)) {
@@ -3998,7 +4098,7 @@ public final class ActivityThread {
            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Handle configuration changed: "
                    + config);
        
            applyConfigurationToResourcesLocked(config);
            diff = applyConfigurationToResourcesLocked(config);
            
            if (mConfiguration == null) {
                mConfiguration = new Configuration();
@@ -4014,7 +4114,20 @@ public final class ActivityThread {
        if (callbacks != null) {
            final int N = callbacks.size();
            for (int i=0; i<N; i++) {
                performConfigurationChanged(callbacks.get(i), config);
                ComponentCallbacks cb = callbacks.get(i);

                // We removed the old resources object from the mActiveResources
                // cache, now we need to trigger an update for each application.
                if ((diff & ActivityInfo.CONFIG_THEME_RESOURCE) != 0) {
                    if (cb instanceof Activity || cb instanceof Application) {
                        Context context = ((ContextWrapper)cb).getBaseContext();
                        if (context instanceof ContextImpl) {
                            ((ContextImpl)context).refreshResourcesIfNecessary();
                        }
                    }
                }

                performConfigurationChanged(cb, config);
            }
        }
    }
@@ -4579,7 +4692,7 @@ public final class ActivityThread {
                    // We need to apply this change to the resources
                    // immediately, because upon returning the view
                    // hierarchy will be informed about it.
                    if (applyConfigurationToResourcesLocked(newConfig)) {
                    if (applyConfigurationToResourcesLocked(newConfig) != 0) {
                        // This actually changed the resources!  Tell
                        // everyone about it.
                        if (mPendingConfiguration == null ||
+81 −9
Original line number Diff line number Diff line
@@ -22,15 +22,17 @@ import com.google.android.collect.Maps;

import org.xmlpull.v1.XmlPullParserException;

import android.accounts.AccountManager;
import android.accounts.IAccountManager;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.ContentResolver;
import android.content.Context;
import android.content.ContextWrapper;
import android.content.IContentProvider;
import android.content.IIntentReceiver;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.IIntentReceiver;
import android.content.IntentSender;
import android.content.ReceiverCallNotAllowedException;
import android.content.ServiceConnection;
@@ -55,6 +57,8 @@ import android.content.pm.ResolveInfo;
import android.content.pm.ServiceInfo;
import android.content.pm.PackageParser.Package;
import android.content.res.AssetManager;
import android.content.res.Configuration;
import android.content.res.CustomTheme;
import android.content.res.Resources;
import android.content.res.XmlResourceParser;
import android.database.sqlite.SQLiteDatabase;
@@ -164,6 +168,7 @@ class ContextImpl extends Context {

    private static final Object sSync = new Object();
    private static AlarmManager sAlarmManager;
    
    private static PowerManager sPowerManager;
    private static ConnectivityManager sConnectivityManager;
    private static ThrottleManager sThrottleManager;
@@ -200,6 +205,7 @@ class ContextImpl extends Context {
    private DevicePolicyManager mDevicePolicyManager = null;
    private UiModeManager mUiModeManager = null;

     
    private final Object mSync = new Object();

    private File mDatabasesDir;
@@ -236,6 +242,20 @@ class ContextImpl extends Context {
        return mResources;
    }

    /**
     * Refresh resources object which may have been changed by a theme
     * configuration change.
     */
    /* package */ void refreshResourcesIfNecessary() {
        if (mResources == Resources.getSystem()) {
            return;
        }

        if (mPackageInfo.mApplicationInfo.isThemeable) {
            mTheme = null;
        }
    }

    @Override
    public PackageManager getPackageManager() {
        if (mPackageManager != null) {
@@ -272,22 +292,61 @@ class ContextImpl extends Context {
        mThemeResource = resid;
    }

    private int determineDefaultThemeResource() {
        if (getResources() != Resources.getSystem() && mPackageInfo.mApplicationInfo.isThemeable) {
            try {
                Configuration config = ActivityManagerNative.getDefault().getConfiguration();
                if (config.customTheme != null) {
                    int themeId = CustomTheme.getStyleId(this,
                                config.customTheme.getThemePackageName(),
                                config.customTheme.getThemeId());
                    if (themeId == -1) {
                        CustomTheme defaultTheme = CustomTheme.getDefault();
                        if (config.customTheme.equals(defaultTheme)) {
                            return com.android.internal.R.style.Theme;
                        } else {
                            themeId = CustomTheme.getStyleId(this,
                                    defaultTheme.getThemePackageName(),
                                    defaultTheme.getThemeId());
                            if (themeId == -1) {
                                return com.android.internal.R.style.Theme;
                            } else {
                                return themeId;
                            }
                        }
                    } else {
                        return themeId;
                    }
                }
            } catch (RemoteException e) {
                Log.e(TAG, "Unable to access configuration, reverting to original system default theme", e);
            }
        }

        /* Fallback... */
        return com.android.internal.R.style.Theme;
    }
    
    @Override
    public Resources.Theme getTheme() {
        if (mTheme == null) {
            int themeId;
            if (mThemeResource == 0) {
                mThemeResource = com.android.internal.R.style.Theme;
                themeId = determineDefaultThemeResource();
            } else {
                themeId = mThemeResource;
            }

            mTheme = mResources.newTheme();
            mTheme.applyStyle(mThemeResource, true);
            mTheme.applyStyle(themeId, true);
        }
        return mTheme;
    }

    @Override
    public ClassLoader getClassLoader() {
        return mPackageInfo != null ?
                mPackageInfo.getClassLoader() : ClassLoader.getSystemClassLoader();
        return mPackageInfo != null ? mPackageInfo.getClassLoader()
                : ClassLoader.getSystemClassLoader();
    }

    @Override
@@ -1497,7 +1556,8 @@ class ContextImpl extends Context {
                IBinder activityToken, ActivityThread mainThread,
                Resources container) {
        mPackageInfo = packageInfo;
        mResources = mPackageInfo.getResources(mainThread);
        mResources = mPackageInfo.getResources(mainThread,
                packageInfo.mApplicationInfo.isThemeable, false);

        if (mResources != null && container != null
                && container.getCompatibilityInfo().applicationScale !=
@@ -1507,7 +1567,8 @@ class ContextImpl extends Context {
                        " compatiblity info:" + container.getDisplayMetrics());
            }
            mResources = mainThread.getTopLevelResources(
                    mPackageInfo.getResDir(), container.getCompatibilityInfo().copy());
                    mPackageInfo.getResDir(), container.getCompatibilityInfo().copy(),
                    packageInfo.mApplicationInfo.isThemeable);
        }
        mMainThread = mainThread;
        mContentResolver = new ApplicationContentResolver(this, mainThread);
@@ -1947,6 +2008,16 @@ class ContextImpl extends Context {
            }
        }

        @Override
        public List<PackageInfo> getInstalledThemePackages() {
            try {
                return mPM.getInstalledThemePackages();
            } catch (RemoteException e) {
                throw new RuntimeException("Package manager has died", e);
            }
        }        


        @Override
        public List<ApplicationInfo> getInstalledApplications(int flags) {
            try {
@@ -2187,7 +2258,8 @@ class ContextImpl extends Context {
            }
            Resources r = mContext.mMainThread.getTopLevelResources(
                    app.uid == Process.myUid() ? app.sourceDir
                    : app.publicSourceDir, mContext.mPackageInfo);
                    : app.publicSourceDir, mContext.mPackageInfo,
                    app.isThemeable);
            if (r != null) {
                return r;
            }
+31 −0
Original line number Diff line number Diff line
@@ -299,6 +299,17 @@ public abstract class ContentResolver {
            // with sufficient testing.
            return new FileInputStream(uri.getPath());
        } else {
            // This is a work around for the following bug.
            // If an asset is stored in a separate file, then AssetFileDescriptor.createInputStream
            // works. However, if an asset is stored in .apk or .zip file, then
            // AssetFileDescriptor.createInputStream returns a stream which does not
            // contain valid data (I can repro the bug using SDK 1.1 and "regular" apk).
            // To work around the bug, we try to get the input stream from AssetManager
            // first and only if that failed, fall back to the "standard" approach.
            InputStream stream = openInputStreamEx(uri);
            if (stream != null) {
                return stream;
            }
            AssetFileDescriptor fd = openAssetFileDescriptor(uri, "r");
            try {
                return fd != null ? fd.createInputStream() : null;
@@ -308,6 +319,26 @@ public abstract class ContentResolver {
        }
    }

    private InputStream openInputStreamEx(Uri uri) {
        IContentProvider provider = acquireProvider(uri);
        ContentProvider cp = null;
        if (provider == null) {
            return null;
        }
        if (provider instanceof ContentProvider.Transport) {
            cp = ((ContentProvider.Transport)provider).getContentProvider();
        } else if (provider instanceof ContentProvider) {
            cp = (ContentProvider)provider;
        }
        if (cp == null) {
            return null;
        }
        if (cp instanceof IExtendedContentProvider) {
            return ((IExtendedContentProvider)cp).openInputStream(uri);
        }
        return null;
    }

    /**
     * Synonym for {@link #openOutputStream(Uri, String)
     * openOutputStream(uri, "w")}.
Loading