Skip to content

Commit

Permalink
Add SettingsManager.
Browse files Browse the repository at this point in the history
Add new APIs for changing a subset of system settings.

Protected by cyanogenmod.permission.MODIFY_NETWORK_SETTINGS:
    - Add ability to toggle airplane mode on/off.
    - Add ability to toggle mobile data on/off.

Protected by android.permission.REBOOT:
    - Add ability to shutdown or reboot the device.

Change-Id: I5e943be11260c58afa664f1702c0ecb4413528fe
  • Loading branch information
Matt Garnes committed Aug 6, 2015
1 parent 5b61a21 commit 0cdb1d5
Show file tree
Hide file tree
Showing 11 changed files with 440 additions and 0 deletions.
9 changes: 9 additions & 0 deletions api/cm_current.txt
Expand Up @@ -236,6 +236,14 @@ package cyanogenmod.app {
field public static final int PROFILES_STATE_ENABLED = 1; // 0x1
}

public class SettingsManager {
method public static cyanogenmod.app.SettingsManager getInstance(android.content.Context);
method public void rebootDevice();
method public void setAirplaneModeEnabled(boolean);
method public void setMobileDataEnabled(boolean);
method public void shutdownDevice();
}

public class StatusBarPanelCustomTile implements android.os.Parcelable {
ctor public StatusBarPanelCustomTile(java.lang.String, java.lang.String, java.lang.String, int, java.lang.String, int, int, cyanogenmod.app.CustomTile, android.os.UserHandle);
ctor public StatusBarPanelCustomTile(java.lang.String, java.lang.String, java.lang.String, int, java.lang.String, int, int, cyanogenmod.app.CustomTile, android.os.UserHandle, long);
Expand Down Expand Up @@ -285,6 +293,7 @@ package cyanogenmod.platform {

public static final class Manifest.permission {
ctor public Manifest.permission();
field public static final java.lang.String MODIFY_SETTINGS = "cyanogenmod.permission.MODIFY_SETTINGS";
field public static final java.lang.String PUBLISH_CUSTOM_TILE = "cyanogenmod.permission.PUBLISH_CUSTOM_TILE";
}

Expand Down
@@ -0,0 +1,158 @@
/*
* Copyright (c) 2011-2015 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 org.cyanogenmod.platform.internal;

import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.os.IBinder;

import android.os.IPowerManager;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.UserHandle;
import android.provider.Settings;
import android.telephony.TelephonyManager;
import android.util.Log;
import com.android.server.SystemService;
import cyanogenmod.app.CMContextConstants;
import cyanogenmod.app.ISettingsManager;
import cyanogenmod.app.SettingsManager;

import java.io.ByteArrayInputStream;
import java.security.PublicKey;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.security.interfaces.RSAPublicKey;

/** {@hide} */
public class SettingsManagerService extends SystemService {

private static final String TAG = "CMSettingsService";

private Context mContext;
private TelephonyManager mTelephonyManager;

public SettingsManagerService(Context context) {
super(context);
mContext = context;
publishBinderService(CMContextConstants.CM_SETTINGS_SERVICE, mService);
}

@Override
public void onStart() {
mTelephonyManager = (TelephonyManager)
mContext.getSystemService(Context.TELEPHONY_SERVICE);
}

private void enforceModifyNetworkSettingsPermission() {
mContext.enforceCallingOrSelfPermission(SettingsManager.MODIFY_NETWORK_SETTINGS_PERMISSION,
"You do not have permissions to change system network settings.");
}

private void enforceShutdownPermission() {
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.REBOOT,
"You do not have permissions to shut down the device.");
}

private final IBinder mService = new ISettingsManager.Stub() {

@Override
public void setAirplaneModeEnabled(boolean enabled) {
enforceModifyNetworkSettingsPermission();
/*
* We need to clear the caller's identity in order to
* allow this method call to modify settings
* not allowed by the caller's permissions.
*/
long token = clearCallingIdentity();
setAirplaneModeEnabledInternal(enabled);
restoreCallingIdentity(token);
}

@Override
public void setMobileDataEnabled(boolean enabled) {
enforceModifyNetworkSettingsPermission();
/*
* We need to clear the caller's identity in order to
* allow this method call to modify settings
* not allowed by the caller's permissions.
*/
long token = clearCallingIdentity();
setMobileDataEnabledInternal(enabled);
restoreCallingIdentity(token);
}

@Override
public void shutdown() {
enforceShutdownPermission();
/*
* We need to clear the caller's identity in order to
* allow this method call to modify settings
* not allowed by the caller's permissions.
*/
long token = clearCallingIdentity();
shutdownInternal(false);
restoreCallingIdentity(token);
}

@Override
public void reboot() {
enforceShutdownPermission();
/*
* We need to clear the caller's identity in order to
* allow this method call to modify settings
* not allowed by the caller's permissions.
*/
long token = clearCallingIdentity();
shutdownInternal(true);
restoreCallingIdentity(token);
}
};

private void setAirplaneModeEnabledInternal(boolean enabled) {
// Change the system setting
Settings.Global.putInt(mContext.getContentResolver(), Settings.Global.AIRPLANE_MODE_ON,
enabled ? 1 : 0);

// Post the intent
Intent intent = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED);
intent.putExtra("state", enabled);
mContext.sendBroadcastAsUser(intent, UserHandle.ALL);
}

private void setMobileDataEnabledInternal(boolean enabled) {
mTelephonyManager.setDataEnabled(enabled);
}

private void shutdownInternal(boolean reboot) {
IPowerManager pm = IPowerManager.Stub.asInterface(
ServiceManager.getService(Context.POWER_SERVICE));
try {
if (reboot) {
pm.reboot(false, null, false);
} else {
pm.shutdown(false, false);
}
} catch (RemoteException e) {
Log.d(TAG, "Unable to shutdown.");
}
}
}

7 changes: 7 additions & 0 deletions cm/res/AndroidManifest.xml
Expand Up @@ -35,6 +35,13 @@
android:icon="@drawable/ic_launcher_cyanogenmod"
android:protectionLevel="normal" />

<!-- Allows system applications to make changes to a subset of system network settings -->
<permission android:name="cyanogenmod.permission.MODIFY_NETWORK_SETTINGS"
android:label="@string/permlab_modifyNetworkSettings"
android:description="@string/permdesc_modifyNetworkSettings"
android:icon="@drawable/ic_launcher_cyanogenmod"
android:protectionLevel="system|signature" />

<application android:process="system"
android:persistent="true"
android:hasCode="false"
Expand Down
3 changes: 3 additions & 0 deletions cm/res/res/values/strings.xml
Expand Up @@ -21,6 +21,9 @@
<string name="permlab_publishCustomTile">create a custom tile within quick settings panel</string>
<string name="permdesc_publishCustomTile">Allows an app to publish a quick settings tile.</string>

<string name="permlab_modifyNetworkSettings">change system network settings</string>
<string name="permdesc_modifyNetworkSettings">Allows an app to make changes to a restricted set of system network settings.</string>

<string name="permlab_bindCustomTileListenerService">bind to a custom tile listener service</string>
<string name="permdesc_bindCustomTileListenerService">Allows the app to bind to the top-level interface of a custom tile listener service.</string>

Expand Down
11 changes: 11 additions & 0 deletions src/java/cyanogenmod/app/CMContextConstants.java
Expand Up @@ -50,4 +50,15 @@ private CMContextConstants() {
* @hide
*/
public static final String CM_PROFILE_SERVICE = "profile";

/**
* Use with {@link android.content.Context#getSystemService} to retrieve a
* {@link cyanogenmod.app.SettingsManager} changing system settings.
*
* @see android.content.Context#getSystemService
* @see cyanogenmod.app.SettingsManager
*
* @hide
*/
public static final String CM_SETTINGS_SERVICE = "cmsettings";
}
27 changes: 27 additions & 0 deletions src/java/cyanogenmod/app/ISettingsManager.aidl
@@ -0,0 +1,27 @@
/* //device/java/android/android/app/IProfileManager.aidl
**
** 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;

/** {@hide} */
interface ISettingsManager
{
void setAirplaneModeEnabled(boolean enabled);
void setMobileDataEnabled(boolean enabled);
void shutdown();
void reboot();
}

0 comments on commit 0cdb1d5

Please sign in to comment.