replicant-vendor_cmsdk/src/java/cyanogenmod/app/ProfileManager.java

556 lines
18 KiB
Java

/*
* Copyright (C) 2015 The CyanogenMod 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 cyanogenmod.app;
import java.util.UUID;
import android.annotation.SdkConstant;
import android.annotation.SdkConstant.SdkConstantType;
import android.app.NotificationGroup;
import android.content.Context;
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;
/**
* <p>
* The ProfileManager allows you to create {@link Profile}s and {@link ProfileGroup}s to create
* specific behavior states depending on triggers from hardware devices changing states, such as:
*
* WiFi being enabled
* WiFi connecting to a certain AP
* Bluetooth connecting to a certain device
* Bluetooth disconnecting to a certain device
* NFC tag being scanned
*
* Depending on these triggers, you can override connection settings, lockscreen modes, media
* stream volumes and various other settings.
*<p>
*
* To get the instance of this class, utilize ProfileManager#getInstance(Context context)
*
* This manager requires the {@link cyanogenmod.platform.Manifest.permission.MODIFY_PROFILES}
* permission.
*
* @see cyanogenmod.app.Profile
* @see cyanogenmod.app.ProfileGroup
*/
public class ProfileManager {
private static IProfileManager sService;
private Context mContext;
private static final String TAG = "ProfileManager";
private static final String SYSTEM_PROFILES_ENABLED = "system_profiles_enabled";
/**
* <p>Broadcast Action: A new profile has been selected. This can be triggered by the user
* or by calls to the ProfileManagerService / Profile.</p>
*/
public static final String INTENT_ACTION_PROFILE_SELECTED =
"cyanogenmod.platform.intent.action.PROFILE_SELECTED";
/**
* <p>Broadcast Action: Current profile has been updated. This is triggered every time the
* currently active profile is updated, instead of selected.</p>
* <p> For instance, this includes profile updates caused by a locale change, which doesn't
* trigger a profile selection, but causes its name to change.</p>
*/
public static final String INTENT_ACTION_PROFILE_UPDATED =
"cyanogenmod.platform.intent.action.PROFILE_UPDATED";
/**
* Extra for {@link #INTENT_ACTION_PROFILE_SELECTED} and {@link #INTENT_ACTION_PROFILE_UPDATED}:
* The name of the newly activated or updated profile
*/
public static final String EXTRA_PROFILE_NAME = "name";
/**
* Extra for {@link #INTENT_ACTION_PROFILE_SELECTED} and {@link #INTENT_ACTION_PROFILE_UPDATED}:
* The string representation of the UUID of the newly activated or updated profile
*/
public static final String EXTRA_PROFILE_UUID = "uuid";
/**
* Extra for {@link #INTENT_ACTION_PROFILE_SELECTED}:
* The name of the previously active profile
*/
public static final String EXTRA_LAST_PROFILE_NAME = "lastName";
/**
* Extra for {@link #INTENT_ACTION_PROFILE_SELECTED}:
* The string representation of the UUID of the previously active profile
*/
public static final String EXTRA_LAST_PROFILE_UUID = "uuid";
/**
* Activity Action: Shows a profile picker.
* <p>
* Input: {@link #EXTRA_PROFILE_EXISTING_UUID}, {@link #EXTRA_PROFILE_SHOW_NONE},
* {@link #EXTRA_PROFILE_TITLE}.
* <p>
* Output: {@link #EXTRA_PROFILE_PICKED_UUID}.
*/
@SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
public static final String ACTION_PROFILE_PICKER =
"cyanogenmod.platform.intent.action.PROFILE_PICKER";
/**
* Constant for NO_PROFILE
*/
public static final UUID NO_PROFILE =
UUID.fromString("00000000-0000-0000-0000-000000000000");
/**
* Given to the profile picker as a boolean. Whether to show an item for
* deselect the profile. If the "None" item is picked,
* {@link #EXTRA_PROFILE_PICKED_UUID} will be {@link #NO_PROFILE}.
*
* @see #ACTION_PROFILE_PICKER
*/
public static final String EXTRA_PROFILE_SHOW_NONE =
"cyanogenmod.platform.intent.extra.profile.SHOW_NONE";
/**
* Given to the profile picker as a {@link UUID} string representation. The {@link UUID}
* representation of the current profile, which will be used to show a checkmark next to
* the item for this {@link UUID}. If the item is {@link #NO_PROFILE} then "None" item
* is selected if {@link #EXTRA_PROFILE_SHOW_NONE} is enabled. Otherwise, the current
* profile is selected.
*
* @see #ACTION_PROFILE_PICKER
*/
public static final String EXTRA_PROFILE_EXISTING_UUID =
"cyanogenmod.platform.extra.profile.EXISTING_UUID";
/**
* Given to the profile picker as a {@link CharSequence}. The title to
* show for the profile picker. This has a default value that is suitable
* in most cases.
*
* @see #ACTION_PROFILE_PICKER
*/
public static final String EXTRA_PROFILE_TITLE =
"cyanogenmod.platform.intent.extra.profile.TITLE";
/**
* Returned from the profile picker as a {@link UUID} string representation.
* <p>
* It will be one of:
* <li> the picked profile,
* <li> null if the "None" item was picked.
*
* @see #ACTION_PROFILE_PICKER
*/
public static final String EXTRA_PROFILE_PICKED_UUID =
"cyanogenmod.platform.intent.extra.profile.PICKED_UUID";
/**
* Broadcast intent action indicating that Profiles has been enabled or disabled.
* One extra provides this state as an int.
*
* @see #EXTRA_PROFILES_STATE
*/
@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
public static final String PROFILES_STATE_CHANGED_ACTION =
"cyanogenmod.platform.app.profiles.PROFILES_STATE_CHANGED";
/**
* The lookup key for an int that indicates whether Profiles are enabled or
* disabled. Retrieve it with {@link android.content.Intent#getIntExtra(String,int)}.
*
* @see #PROFILES_STATE_DISABLED
* @see #PROFILES_STATE_ENABLED
*/
public static final String EXTRA_PROFILES_STATE = "profile_state";
/**
* Set the resource id theme to use for the dialog picker activity.<br/>
* The default theme is <code>com.android.internal.R.Theme_Holo_Dialog_Alert</code>.
*
* @see #ACTION_PROFILE_PICKER
*/
public static final String EXTRA_PROFILE_DIALOG_THEME =
"cyanogenmod.platform.intent.extra.profile.DIALOG_THEME";
/**
* Profiles are disabled.
*
* @see #PROFILES_STATE_CHANGED_ACTION
*/
public static final int PROFILES_STATE_DISABLED = 0;
/**
* Profiles are enabled.
*
* @see #PROFILES_STATE_CHANGED_ACTION
*/
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();
if (appContext != null) {
mContext = appContext;
} else {
mContext = context;
}
sService = getService();
mEmptyProfile = new Profile("EmptyProfile");
}
/**
* Get or create an instance of the {@link cyanogenmod.app.ProfileManager}
* @param context
* @return {@link ProfileManager}
*/
public static ProfileManager getInstance(Context context) {
if (sProfileManagerInstance == null) {
sProfileManagerInstance = new ProfileManager(context);
}
return sProfileManagerInstance;
}
/** @hide */
static public IProfileManager getService() {
if (sService != null) {
return sService;
}
IBinder b = ServiceManager.getService(CMContextConstants.CM_PROFILE_SERVICE);
sService = IProfileManager.Stub.asInterface(b);
return sService;
}
@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);
}
}
}
/**
* Set the active {@link Profile} by {@link UUID}
* @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);
}
}
}
/**
* Get the active {@link Profile}
* @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;
}
}
/**
* Add a {@link Profile} that can be selected by the user
* @param profile a {@link Profile} object
*/
public void addProfile(Profile profile) {
try {
getService().addProfile(profile);
} catch (RemoteException e) {
Log.e(TAG, e.getLocalizedMessage(), e);
}
}
/**
* Remove a {@link Profile} from user selection
* @param profile a {@link Profile} object
*/
public void removeProfile(Profile profile) {
try {
getService().removeProfile(profile);
} catch (RemoteException e) {
Log.e(TAG, e.getLocalizedMessage(), e);
}
}
/**
* Update a {@link Profile} object
* @param profile a {@link Profile} object
*/
public void updateProfile(Profile profile) {
try {
getService().updateProfile(profile);
} catch (RemoteException e) {
Log.e(TAG, e.getLocalizedMessage(), e);
}
}
/**
* Get the {@link Profile} object by its literal name
* @param profileName name associated with the profile
* @return profile a {@link Profile} object
*/
@Deprecated
public Profile getProfile(String profileName) {
try {
return getService().getProfileByName(profileName);
} catch (RemoteException e) {
Log.e(TAG, e.getLocalizedMessage(), e);
}
return null;
}
/**
* Get a {@link Profile} via {@link UUID}
* @param profileUuid {@link UUID} associated with the profile
* @return {@link Profile}
*/
public Profile getProfile(UUID profileUuid) {
try {
return getService().getProfile(new ParcelUuid(profileUuid));
} catch (RemoteException e) {
Log.e(TAG, e.getLocalizedMessage(), e);
}
return null;
}
/**
* Get the profile names currently available to the user
* @return {@link String[]} of profile names
*/
public String[] getProfileNames() {
try {
Profile[] profiles = getService().getProfiles();
String[] names = new String[profiles.length];
for (int i = 0; i < profiles.length; i++) {
names[i] = profiles[i].getName();
}
return names;
} catch (RemoteException e) {
Log.e(TAG, e.getLocalizedMessage(), e);
}
return null;
}
/**
* Get the {@link Profile}s currently available to the user
* @return {@link Profile[]}
*/
public Profile[] getProfiles() {
try {
return getService().getProfiles();
} catch (RemoteException e) {
Log.e(TAG, e.getLocalizedMessage(), e);
}
return null;
}
/**
* Check if a {@link Profile} exists via its literal name
* @param profileName a profile name
* @return whether or not the profile exists
*/
public boolean profileExists(String profileName) {
try {
return getService().profileExistsByName(profileName);
} catch (RemoteException e) {
Log.e(TAG, e.getLocalizedMessage(), e);
// To be on the safe side, we'll return "true", to prevent duplicate profiles
// from being created.
return true;
}
}
/**
* Check if a {@link Profile} exists via its {@link UUID}
* @param profileUuid the profiles {@link UUID}
* @return whether or not the profile exists
*/
public boolean profileExists(UUID profileUuid) {
try {
return getService().profileExists(new ParcelUuid(profileUuid));
} catch (RemoteException e) {
Log.e(TAG, e.getLocalizedMessage(), e);
// To be on the safe side, we'll return "true", to prevent duplicate profiles
// from being created.
return true;
}
}
/**
* Check if a NotificationGroup exists
* @param notificationGroupName the name of the notification group
* @return whether or not the notification group exists
* @hide
*/
public boolean notificationGroupExists(String notificationGroupName) {
try {
return getService().notificationGroupExistsByName(notificationGroupName);
} catch (RemoteException e) {
Log.e(TAG, e.getLocalizedMessage(), e);
// To be on the safe side, we'll return "true", to prevent duplicate notification
// groups from being created.
return true;
}
}
/**
* Get the currently available NotificationGroups
* @return NotificationGroup
* @hide
*/
public NotificationGroup[] getNotificationGroups() {
try {
return getService().getNotificationGroups();
} catch (RemoteException e) {
Log.e(TAG, e.getLocalizedMessage(), e);
}
return null;
}
/**
* Add a NotificationGroup to the available list
* @param group NotificationGroup
* @hide
*/
public void addNotificationGroup(NotificationGroup group) {
try {
getService().addNotificationGroup(group);
} catch (RemoteException e) {
Log.e(TAG, e.getLocalizedMessage(), e);
}
}
/**
* Remove a NotificationGroup from the available list
* @param group NotificationGroup
* @hide
*/
public void removeNotificationGroup(NotificationGroup group) {
try {
getService().removeNotificationGroup(group);
} catch (RemoteException e) {
Log.e(TAG, e.getLocalizedMessage(), e);
}
}
/**
* Update a NotificationGroup from the available list
* @param group NotificationGroup
* @hide
*/
public void updateNotificationGroup(NotificationGroup group) {
try {
getService().updateNotificationGroup(group);
} catch (RemoteException e) {
Log.e(TAG, e.getLocalizedMessage(), e);
}
}
/**
* Get a NotificationGroup for a specific package
* @param pkg name of the package
* @hide
*/
public NotificationGroup getNotificationGroupForPackage(String pkg) {
try {
return getService().getNotificationGroupForPackage(pkg);
} catch (RemoteException e) {
Log.e(TAG, e.getLocalizedMessage(), e);
}
return null;
}
/**
* Get a NotificationGroup from the available list via {@link UUID}
* @param uuid {@link UUID} of the notification group
* @hide
*/
public NotificationGroup getNotificationGroup(UUID uuid) {
try {
return getService().getNotificationGroup(new ParcelUuid(uuid));
} catch (RemoteException e) {
Log.e(TAG, e.getLocalizedMessage(), e);
}
return null;
}
/**
* Get an active {@link ProfileGroup} via its package name
* @param packageName the package name associated to the profile group
* @return {@link ProfileGroup}
* @hide
*/
public ProfileGroup getActiveProfileGroup(String packageName) {
NotificationGroup notificationGroup = getNotificationGroupForPackage(packageName);
if (notificationGroup == null) {
ProfileGroup defaultGroup = getActiveProfile().getDefaultGroup();
return defaultGroup;
}
return getActiveProfile().getProfileGroup(notificationGroup.getUuid());
}
/**
* Reset all profiles, groups, and notification groups to default state
*/
public void resetAll() {
try {
getService().resetAll();
} catch (RemoteException e) {
Log.e(TAG, e.getLocalizedMessage(), e);
} catch (SecurityException e) {
Log.e(TAG, e.getLocalizedMessage(), e);
}
}
}