diff --git a/cm/lib/main/java/org/cyanogenmod/platform/internal/ProfileManagerService.java b/cm/lib/main/java/org/cyanogenmod/platform/internal/ProfileManagerService.java index aa7c27c..1a93c86 100644 --- a/cm/lib/main/java/org/cyanogenmod/platform/internal/ProfileManagerService.java +++ b/cm/lib/main/java/org/cyanogenmod/platform/internal/ProfileManagerService.java @@ -18,7 +18,11 @@ package org.cyanogenmod.platform.internal; import android.content.ComponentName; import android.content.ServiceConnection; +import android.database.ContentObserver; +import android.net.Uri; +import android.os.Message; import com.android.internal.policy.IKeyguardService; +import cyanogenmod.providers.CMSettings; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; import org.xmlpull.v1.XmlPullParserFactory; @@ -70,6 +74,8 @@ public class ProfileManagerService extends SystemService { /* package */ static final File PROFILE_FILE = new File(Environment.getSystemSecureDirectory(), "profiles.xml"); + private static final int MSG_SEND_PROFILE_STATE = 10; + private Map mProfiles; // Match UUIDs and names, used for reverse compatibility @@ -89,6 +95,7 @@ public class ProfileManagerService extends SystemService { private boolean mDirty; private BackupManager mBackupManager; private ProfileTriggerHelper mTriggerHelper; + private Profile mEmptyProfile; private Runnable mBindKeyguard = new Runnable() { @Override @@ -127,10 +134,41 @@ public class ProfileManagerService extends SystemService { } }; + private final Handler.Callback mHandlerCallback = new Handler.Callback() { + @Override + public boolean handleMessage(Message msg) { + switch (msg.what) { + case MSG_SEND_PROFILE_STATE: + Intent newState = new Intent(ProfileManager.PROFILES_STATE_CHANGED_ACTION); + newState.putExtra(ProfileManager.EXTRA_PROFILES_STATE, msg.arg1); + + mContext.sendBroadcastAsUser(newState, UserHandle.ALL); + + + return true; + } + return false; + } + }; + + private class ProfilesObserver extends ContentObserver { + public ProfilesObserver(Handler handler) { + super(handler); + } + + @Override + public void onChange(boolean selfChange, Uri uri) { + int state = CMSettings.System.getInt(mContext.getContentResolver(), + CMSettings.System.SYSTEM_PROFILES_ENABLED, + ProfileManager.PROFILES_STATE_ENABLED); + mHandler.obtainMessage(MSG_SEND_PROFILE_STATE, state, 0 /* unused */).sendToTarget(); + } + } + public ProfileManagerService(Context context) { super(context); mContext = context; - mHandler = new Handler(); + mHandler = new Handler(mHandlerCallback); publishBinderService(CMContextConstants.CM_PROFILE_SERVICE, mService); } @@ -149,6 +187,10 @@ public class ProfileManagerService extends SystemService { filter.addAction(Intent.ACTION_LOCALE_CHANGED); filter.addAction(Intent.ACTION_SHUTDOWN); mContext.registerReceiver(mIntentReceiver, filter); + + mContext.getContentResolver().registerContentObserver( + CMSettings.System.getUriFor(CMSettings.System.SYSTEM_PROFILES_ENABLED), + false, new ProfilesObserver(mHandler), UserHandle.USER_ALL); } private void bindKeyguard() { @@ -178,6 +220,7 @@ public class ProfileManagerService extends SystemService { mProfiles = new HashMap(); mProfileNames = new HashMap(); mGroups = new HashMap(); + mEmptyProfile = new Profile("EmptyProfile"); mDirty = false; boolean init = skipFile; @@ -214,6 +257,10 @@ public class ProfileManagerService extends SystemService { @Override @Deprecated public boolean setActiveProfileByName(String profileName) { + if (!isEnabled()) { + Log.w(TAG, "Unable to set active profile because profiles are disabled."); + return false; + } if (!mProfileNames.containsKey(profileName)) { // Since profileName could not be casted into a UUID, we can call it a string. Log.w(TAG, "Unable to find profile to set active, based on string: " + profileName); @@ -237,6 +284,10 @@ public class ProfileManagerService extends SystemService { @Override public boolean setActiveProfile(ParcelUuid profileParcelUuid) { + if (!isEnabled()) { + Log.w(TAG, "Unable to set active profile because profiles are disabled."); + return false; + } /* * We need to clear the caller's identity in order to * - allow the profile switch to execute actions @@ -286,6 +337,10 @@ public class ProfileManagerService extends SystemService { @Override public Profile getActiveProfile() { + if (!isEnabled()) { + // Profiles are not enabled, return empty profile + return mEmptyProfile; + } return getActiveProfileInternal(); } @@ -416,6 +471,19 @@ public class ProfileManagerService extends SystemService { } return mGroups.get(uuid.getUuid()); } + + @Override + public boolean isEnabled() { + long token = clearCallingIdentity(); + try { + return CMSettings.System.getIntForUser(mContext.getContentResolver(), + CMSettings.System.SYSTEM_PROFILES_ENABLED, + ProfileManager.PROFILES_STATE_ENABLED, + UserHandle.USER_CURRENT) == ProfileManager.PROFILES_STATE_ENABLED; + } finally { + restoreCallingIdentity(token); + } + } }; private void addProfileInternal(Profile profile) { diff --git a/packages/CMSettingsProvider/res/values/defaults.xml b/packages/CMSettingsProvider/res/values/defaults.xml index fa5cfef..98a9c12 100644 --- a/packages/CMSettingsProvider/res/values/defaults.xml +++ b/packages/CMSettingsProvider/res/values/defaults.xml @@ -23,6 +23,9 @@ 2. Left --> 0 + + true + diff --git a/packages/CMSettingsProvider/src/org/cyanogenmod/cmsettings/CMDatabaseHelper.java b/packages/CMSettingsProvider/src/org/cyanogenmod/cmsettings/CMDatabaseHelper.java index 5d40866..17335e6 100644 --- a/packages/CMSettingsProvider/src/org/cyanogenmod/cmsettings/CMDatabaseHelper.java +++ b/packages/CMSettingsProvider/src/org/cyanogenmod/cmsettings/CMDatabaseHelper.java @@ -251,6 +251,9 @@ public class CMDatabaseHelper extends SQLiteOpenHelper{ loadBooleanSetting(db, CMTableNames.TABLE_SYSTEM, CMSettings.System.NOTIFICATION_LIGHT_MULTIPLE_LEDS_ENABLE, R.bool.def_notification_multiple_leds); + + loadBooleanSetting(db, CMTableNames.TABLE_SYSTEM, CMSettings.System.SYSTEM_PROFILES_ENABLED, + R.bool.def_profiles_enabled); } private void loadGlobalSettings(SQLiteDatabase db) { diff --git a/src/java/cyanogenmod/app/IProfileManager.aidl b/src/java/cyanogenmod/app/IProfileManager.aidl index 21e68cd..091ba55 100644 --- a/src/java/cyanogenmod/app/IProfileManager.aidl +++ b/src/java/cyanogenmod/app/IProfileManager.aidl @@ -47,4 +47,5 @@ interface IProfileManager NotificationGroup getNotificationGroup(in ParcelUuid groupParcelUuid); void resetAll(); + boolean isEnabled(); } diff --git a/src/java/cyanogenmod/app/ProfileManager.java b/src/java/cyanogenmod/app/ProfileManager.java index fa50067..c211dc0 100644 --- a/src/java/cyanogenmod/app/ProfileManager.java +++ b/src/java/cyanogenmod/app/ProfileManager.java @@ -26,12 +26,12 @@ import android.os.IBinder; import android.os.ParcelUuid; import android.os.RemoteException; import android.os.ServiceManager; -import android.provider.Settings; import android.util.Log; import cyanogenmod.app.IProfileManager; import com.android.internal.R; +import cyanogenmod.providers.CMSettings; /** @@ -68,8 +68,6 @@ public class ProfileManager { private static final String TAG = "ProfileManager"; - private static final String SYSTEM_PROFILES_ENABLED = "system_profiles_enabled"; - /** *

Broadcast Action: A new profile has been selected. This can be triggered by the user * or by calls to the ProfileManagerService / Profile.

@@ -214,9 +212,6 @@ public class ProfileManager { */ public static final int PROFILES_STATE_ENABLED = 1; - // A blank profile that is created to be returned if profiles disabled - private static Profile mEmptyProfile; - private static ProfileManager sProfileManagerInstance; private ProfileManager(Context context) { Context appContext = context.getApplicationContext(); @@ -226,7 +221,6 @@ public class ProfileManager { mContext = context; } sService = getService(); - mEmptyProfile = new Profile("EmptyProfile"); } /** @@ -253,14 +247,10 @@ public class ProfileManager { @Deprecated public void setActiveProfile(String profileName) { - if (Settings.System.getInt(mContext.getContentResolver(), - SYSTEM_PROFILES_ENABLED, 1) == 1) { - // Profiles are enabled, return active profile - try { - getService().setActiveProfileByName(profileName); - } catch (RemoteException e) { - Log.e(TAG, e.getLocalizedMessage(), e); - } + try { + getService().setActiveProfileByName(profileName); + } catch (RemoteException e) { + Log.e(TAG, e.getLocalizedMessage(), e); } } @@ -269,14 +259,10 @@ public class ProfileManager { * @param profileUuid the {@link UUID} associated with the profile */ public void setActiveProfile(UUID profileUuid) { - if (Settings.System.getInt(mContext.getContentResolver(), - SYSTEM_PROFILES_ENABLED, 1) == 1) { - // Profiles are enabled, return active profile - try { - getService().setActiveProfile(new ParcelUuid(profileUuid)); - } catch (RemoteException e) { - Log.e(TAG, e.getLocalizedMessage(), e); - } + try { + getService().setActiveProfile(new ParcelUuid(profileUuid)); + } catch (RemoteException e) { + Log.e(TAG, e.getLocalizedMessage(), e); } } @@ -285,21 +271,12 @@ public class ProfileManager { * @return active {@link Profile} */ public Profile getActiveProfile() { - if (Settings.System.getInt(mContext.getContentResolver(), - SYSTEM_PROFILES_ENABLED, 1) == 1) { - // Profiles are enabled, return active profile - try { - return getService().getActiveProfile(); - } catch (RemoteException e) { - Log.e(TAG, e.getLocalizedMessage(), e); - } - return null; - - } else { - // Profiles are not enabled, return the empty profile - return mEmptyProfile; + try { + return getService().getActiveProfile(); + } catch (RemoteException e) { + Log.e(TAG, e.getLocalizedMessage(), e); } - + return null; } /** @@ -555,4 +532,17 @@ public class ProfileManager { Log.e(TAG, e.getLocalizedMessage(), e); } } + + /** + * Check if profiles are currently activated in the system + * @return whether profiles are enabled + */ + public boolean isProfilesEnabled() { + try { + return getService().isEnabled(); + } catch (RemoteException e) { + Log.e(TAG, e.getLocalizedMessage(), e); + } + return false; + } } diff --git a/tests/src/org/cyanogenmod/tests/profiles/unit/ProfileManagerTest.java b/tests/src/org/cyanogenmod/tests/profiles/unit/ProfileManagerTest.java index 1f3f05a..37338b0 100644 --- a/tests/src/org/cyanogenmod/tests/profiles/unit/ProfileManagerTest.java +++ b/tests/src/org/cyanogenmod/tests/profiles/unit/ProfileManagerTest.java @@ -20,6 +20,7 @@ import android.test.AndroidTestCase; import android.test.suitebuilder.annotation.SmallTest; import cyanogenmod.app.ProfileManager; import cyanogenmod.app.IProfileManager; +import cyanogenmod.providers.CMSettings; /** * Created by adnan on 7/15/15. @@ -43,4 +44,30 @@ public class ProfileManagerTest extends AndroidTestCase { IProfileManager iProfileManager = mProfileManager.getService(); assertNotNull(iProfileManager); } + + @SmallTest + public void testManagerProfileIsEnabled() { + // first enable profiles + final String enabledValue = "1"; + assertTrue(CMSettings.System.putString(getContext().getContentResolver(), + CMSettings.System.SYSTEM_PROFILES_ENABLED, enabledValue)); + + // check that we successfully enabled them via system setting + assertEquals(enabledValue, CMSettings.System.getString(getContext().getContentResolver(), + CMSettings.System.SYSTEM_PROFILES_ENABLED)); + + // check that profile manger returns true + assertTrue(mProfileManager.isProfilesEnabled()); + + // now disable the setting + final String disabledValue = "0"; + assertTrue(CMSettings.System.putString(getContext().getContentResolver(), + CMSettings.System.SYSTEM_PROFILES_ENABLED, disabledValue)); + + // check that we successfully disable them via system setting + assertEquals(disabledValue, CMSettings.System.getString(getContext().getContentResolver(), + CMSettings.System.SYSTEM_PROFILES_ENABLED)); + + assertFalse(mProfileManager.isProfilesEnabled()); + } }